我正在研究遗传算法,我找到了一个有效的代码,现在我想了解,但是我看到了这个返回语句:
return sum(1 for expected, actual in zip(target, guess)
if expected == actual)
它做了什么?
以下是完整代码:
main.py:
from population import *
while True:
child = mutate(bestParent)
childFitness = get_fitness(child)
if bestFitness >= childFitness:
continue
print(child)
if childFitness >= len(bestParent):
break
bestFitness = childFitness
bestParent = child
population.py:
import random
geneSet = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!.,1234567890-_=+!@#$%^&*():'[]\""
target = input()
def generate_parent(length):
genes = []
while len(genes) < length:
sampleSize = min(length - len(genes), len(geneSet))
genes.extend(random.sample(geneSet, sampleSize))
parent = ""
for i in genes:
parent += i
return parent
def get_fitness(guess):
return sum(1 for expected, actual in zip(target, guess)
if expected == actual)
def mutate(parent):
index = random.randrange(0, len(parent))
childGenes = list(parent)
newGene, alternate = random.sample(geneSet, 2)
childGenes[index] = alternate \
if newGene == childGenes[index] \
else newGene
child = ""
for i in childGenes:
child += i
return child
def display(guess):
timeDiff = datetime.datetime.now() - startTime
fitness = get_fitness(guess)
print(str(guess) + "\t" + str(fitness) + "\t" + str(timeDiff))
random.seed()
bestParent = generate_parent(len(target))
bestFitness = get_fitness(bestParent)
print(bestParent)
这是一个工作遗传算法的完整代码。我修改了一些部分,使它对我来说更具可读性。
return语句位于population.py文件的get_fitness函数中。
答案 0 :(得分:4)
让我们打破这一点:
return sum(1 for expected, actual in zip(target, guess)
if expected == actual)
可以写成:
total = 0
for i in range(len(target)):
if target[i] == guess[i]:
total = total + 1
return total
zip(a, b)
列出了来自a
和b
的商品对,例如:
zip([1, 2, 3], ['a', 'b', 'c'])
收益[(1, 'a'), (2, 'b'), (3, 'c')]
。因此,zip(target, guess)
表达式会返回target
中第一项和guess
的第一项的列表,然后是target
中的第二项和guess
中的第二项等等。
for expected, actual in zip()
位解包来自zip()
输出的值对,因此该对中的第一个(来自target
)转到变量expected
,该对中的第二个(来自guess
)转到变量actual
。
如果1 ... if expected == actual
中的值等于zip()
中的值,则expected
位表示&#34;为actual
中的每个项发出值1。
sum()
将for循环中的1
值加起来。
钽哒!现在,您可以获得预期值和实际值相同的项目数。写这种方式有几个原因:
答案 1 :(得分:1)
我认为它会返回实际=预期的匹配总数。基本上我认为它是检查算法模型能够正确预测的次数
答案 2 :(得分:1)
这是一种List Comprehension使用zip()函数。
基本上,代码说:
答案 3 :(得分:1)
有几件事情在发生:
return sum(...)
这意味着您要返回一个号码。
sum
的内部部分是generator expression
,它创建并运行隐式循环。
在这种情况下,1 for expected, actual in zip(target, guess) if expected == actual
创建一系列1
值,每次保护条件为真(expected == actual
)时都会创建一个条目。
因此,这一行有效地创建了代码:sum(1, 1, 1, 1, ...)
在生成器表达式中,您有一个zip
调用。 zip表达式将采用两个(或更多!)序列,并将它们转换为具有两个(或更多!)值的元组的单个序列。也就是说,zip(['a', 'b', 'c'], [1, 2, 3])
将生成一个类似[('a', 1), ('b', 2), ('c', 3)]
的序列。
因此,如果您的expected
为[1, 2, 3]
且actual
为[1, 1, 3]
,您将获得如下拉链结果:
expected = [1, 2, 3]
actual = [1, 1, 3]
zip(expected, actual) # [(1, 1), (2, 1), (3, 3)]
生成器表达式包含一个for
,它使用曾经被称为&#34; tuple unpacking&#34;从单个聚合(元组)值中为其target_list
分配多个目标。
因此,当zip表达式生成(1, 1)
时,for expected, actual
会将其解包为expected=1, actual=1
。
因此,zip
采用两个等长序列并将其对应的元素配对:a [0]与b [0],a [1]与b [1]等。{{1} } generator expression将这些元素分配给名为for
和expected
的变量。 actual
生成器条件部分比较for...if
值,并生成值或不生成值。因此,保证结果序列的长度小于或等于输入序列的长度,但您不知道它的长度。生成器的表达式部分只是expected == actual
。所以你有一个1的可变长度序列。它的不 1或0。它是1或没有条目。添加所有1,这就是结果。