将列表中的项替换为另一个列表中的相应项(Python)

时间:2014-02-25 15:46:25

标签: python list

我正在与GA合作,需要修改基因组。我已经将基因组中的最小值设置为表示随机过程的“标志”。因此,当函数接受包含范围[0,8]中的输入时,GA将仅选择值[4,8]。任何“4”的实例都需要用另一个列表中的数字替换为[0,4]。

我目前使用以下代码实现此目的:

#-------------------------------------------------------------------------------
def modify_chromosome(chromosome):
    # If value == replace option, replace from another list
    for (index,value) in enumerate(chromosome):
        # Note "<=" necessary in case GA mutates the values
        if value <= flag_option:
            chromosome[index] = changed_value[index]
    # This changes the actual chromosome in the GA
    return chromosome

其中changed_value列表先前已定义为

changed_value = random.randint(0,flag_option,len(num_entries))

上面的代码工作正常,但迭代这样的列表非常耗时(整个运行时间的约10%在此函数中)。

我的问题: 有没有更有效的方法来实现上面的代码块?

提前致谢。

1 个答案:

答案 0 :(得分:0)

您可以做的最好的事情是使用izip遍历两个列表,这样每次运行index命令时都不会创建enumerate(chromosome)列表。

from itertools import izip

changed_value = random.randint(0,flag_option,len(num_entries))
chromosome = [c if c <= flag_option else v  
                for c, v in izip(chromosome, changed_value)]

编辑:所以我使用以下脚本进行了一些基准测试:

from itertools import izip
import random
import timeit

def test_setup(n, flag_option=4):
    setup = 'from itertools import izip\nfrom random import randint\n'
    setup += 'flag_option = {}\n'.format(flag_option)
    setup += 'changed_val = [randint(0, flag_option) for _ in xrange({})]\n'.format(n)
    setup += 'chromosome = [randint(0, 8) for _ in xrange({})]\n'.format(n)
    return setup

test_izip  = '[v if c <= flag_option else c '
test_izip += 'for c, v in izip(chromosome, changed_val)]'

test_zip   = '[v if c <= flag_option else c '
test_zip  += 'for c, v in zip(chromosome, changed_val)]'

test_enum  = '[changed_val[i] if c <= flag_option else c '
test_enum += 'for i,c in enumerate(chromosome)]'

test_orig  = 'for (i,c) in enumerate(chromosome):\n'
test_orig += '\tif c <= flag_option:\n'
test_orig += '\t\tchromosome[i] = changed_val[i]'

if '__main__' == __name__:
    for n in [10 ** i for i in xrange(7)]:    
        print 'izip {}: '.format(n),
        print min(timeit.Timer(test_izip, setup=test_setup(n)).repeat(7, 1000))

        print 'zip {}: '.format(n),
        print min(timeit.Timer(test_zip, setup=test_setup(n)).repeat(7, 1000))   

        print 'enum {}: '.format(n),
        print min(timeit.Timer(test_enum, setup=test_setup(n)).repeat(7, 1000))   

        print 'orig {}: '.format(n),
        print min(timeit.Timer(test_orig, setup=test_setup(n)).repeat(7, 1000)) 

        print 

结果如下:

izip 10:  0.00132203102112
zip 10:   0.00159502029419
enum 10:  0.00130820274353
orig 10:  0.000921964645386

izip 100:  0.00951504707336
zip 100:   0.01145195961
enum 100:  0.00957798957825
orig 100:  0.00854301452637

izip 1000:  0.0860891342163
zip 1000:   0.109489917755
enum 1000:  0.0958349704742
orig 1000:  0.0862739086151

izip 10000:  0.922410964966
zip 10000:   1.31961488724
enum 10000:  1.00453591347
orig 10000:  0.93142914772

izip 100000:  9.61347794533 
zip 100000:  18.9829239845
enum 100000: 10.6979219913
orig 100000:  9.5124809742

izip 1000000:  100.970448971
zip 1000000:   211.297281027
enum 1000000:  122.404583931
orig 1000000:   94.8837227821

所以在所有事情之后,看起来您的原始代码将是最快的。