Ok, I measured the solution. The inverse solutions are about the same. The straight while about 4 times slower. BUT! Patrik's dirty solution is about 80 times faster for a list of 100,000 random integers [Patrik2 bug fixed] :
import timeit import random def solution_ninjagecko1(lst): for i in xrange(len(lst)-1, -1, -1): if lst[i] % 2 != 0:
It prints on my console:
c:\tmp\_Python\Patrick\so10305762>python a.py range() generated list of the length 30 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, '...'] [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28] [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28] [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28] [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28] random list of the length 100000 [915411, 954538, 794388, 847204, 846603, 454132, 866165, 640004, 930488, 609138, 333405, 986073, 318301, 728151, 996047, 117633, 455353, 581737, 55350, 485030, '...'] solution_ninjagecko1: 2.41921752625 solution_jdi: 2.45477176569 solution_Patrik: 0.0468565138865 solution_Patrik2: 0.024270403082 solution_pepr_reversed: 2.43338888043 solution_pepr: 9.11879694207
So, I tried with a longer list. Using only twice as much is of great importance (on my old computer). Patrik dirty decision behaves very beautifully. This is about 200 times faster than the inverse solutions:
random list of the length 200000 [384592, 170167, 598270, 832363, 123557, 81804, 319315, 445945, 178732, 726600, 516835, 392267, 552608, 40807, 349215, 208111, 880032, 520614, 384119, 350090, '...'] solution_ninjagecko1: 17.362140719 solution_jdi: 17.86837545 solution_Patrik: 0.0957998851809 solution_Patrik2: 0.0500024444448 solution_pepr_reversed: 17.5078452708 solution_pepr: 52.175648581
[Posted after comments by ninjagecko]
The patrik2 fixed solution is about twice as fast as patrick's 2-stage solution.
To simulate the not so frequent removal of elements, a test similar to if v % 2 != 0: was changed to if v % 100 == 0: Then you need to remove about 1% of the items. Obviously, this takes less time. For 500,000 random integers in the list, the results are as follows:
random list of the length 500000 [403512, 138135, 552313, 427971, 42358, 500926, 686944, 304889, 916659, 112636, 791585, 461948, 82622, 522768, 485408, 774048, 447505, 830220, 791421, 580706, '...'] solution_ninjagecko1: 6.79284210703 solution_jdi: 6.84066913532 solution_Patrik: 0.241242951269 solution_Patrik2: 0.162481823807 solution_pepr_reversed: 6.92106007886 solution_pepr: 7.12900522273
Patrick's solution is about 30 times faster.
[Posted on 2012/04/25]
Another solution that works on the spot, which moves forward, is as fast as Patrick’s solution. It does not move the entire tail when an item is removed. Instead, it moves the desired items to their final position, and then cuts the unused tail of the list.
def solution_pepr2(lst): i = 0 for v in lst: lst[i] = v
Compared to the solutions above for v % 100 != 0 :
random list of the length 500000 [533094, 600755, 58260, 295962, 347612, 851487, 523927, 665648, 537403, 238660, 781030, 940052, 878919, 565870, 717745, 408465, 410781, 560173, 51010, 730322, '...'] solution_ninjagecko1: 1.38956896051 solution_jdi: 1.42314502685 solution_Patrik: 0.135545530079 solution_Patrik2: 0.0926935780151 solution_pepr_reversed: 1.43573239178 solution_steveha: 0.122824246805 solution_pepr2: 0.0938177241656 solution_pepr2enum: 0.11096263294