我有一个奇怪的问题想了解。我写了一个简单的遗传密码来猜测这对字母“ab”。有一个循环使用生成随机候选的函数作为第一步。该函数可以工作并且很容易理解,但是,它在导入时不起作用,只有在它位于整个遗传密码模块内部的情况下才起作用。如果我编写另一个具有该功能的模块,然后从那里导入,它就可以正常工作。
这到底是什么?
这是我用来导入函数的代码:
from scratch_2 import generate_random_candidate
print (generate_random_candidate())
这是scratch_2:
import random
import string
target = "ab"
letras = string.ascii_lowercase
tried_candidates = set()
def generate_random_candidate():
while True:
intento = random.choice(letras) + random.choice(letras)
if intento not in tried_candidates:
tried_candidates.add(intento)
return intento
所以这就是完全正常的方法。这是scratch_1,当我从那里导入时,我看到调试功能不起作用,如果我打印tried_candidates,我看到它打印set()、set()、set(),就像它在无限循环内一样。是因为它调用了该函数但没有运行其代码吗?与变量tried_candidates有关吗?相同的功能不应该独立于存储在其中的模块而工作吗?
这是scratch_1,如果我从中导入函数,它什么也不做。
import random
import string
import matplotlib.pyplot as plt
import plotly.graph_objects as go
target = "ab"
letras = string.ascii_lowercase
tried_candidates = set()
def generate_random_candidate():
while True:
intento = random.choice(letras) + random.choice(letras)
if intento not in tried_candidates:
tried_candidates.add(intento)
return intento
def generate_children(parent):
hijos = []
while True:
intento = parent[0] + random.choice(letras)
if intento not in tried_candidates:
hijos.append(intento)
break
while True:
intento = random.choice(letras) + parent[1]
if intento not in tried_candidates:
hijos.append(intento)
break
return hijos
def evaluate_candidate(candidate):
score = 0
if candidate[0] == target[0]:
score += 1
if candidate[1] == target[1]:
score += 1
"""
if candidate[0] == target[1]:
score += 0.1
if candidate[1] == target[0]:
score += 0.1
"""
return score
def g ():
tried_candidates = set()
population_size = 10
population = []
for _ in range(population_size):
population.append(generate_random_candidate())
contador = 1
while True:
tried_candidates.update(population)
scores = []
for candidate in population:
scores.append(evaluate_candidate(candidate))
children = []
Flag = False
for i, score in enumerate(scores):
if score == 2:
Flag = True
break
if score == 1 :
x = generate_children(population[i])
tried_candidates.update(x)
children.extend(generate_children(population[i]))
if len(children) < population_size:
new_candidates = []
for _ in range(population_size - len(children)):
y = generate_random_candidate()
tried_candidates.update(y)
new_candidates.append(y)
children.extend(new_candidates)
population = children
else:
meter = children[population_size:]
population = children[:population_size]
tried_candidates.difference_update(meter)
found = False
for candidate in population:
if evaluate_candidate(candidate) == 2 or Flag == True:
found = True
return contador
contador = contador +1
resultados = []
for i in range (100000):
resultados.append(g())
这里的问题与
tried_candidates
变量有关。由于 tried_candidates
是在 scratch_1
和 scratch_2
中在模块级别定义的一组,因此将 generate_random_candidate
从一个模块导入另一个模块可能会导致不同的实例或行为,尤其是在每次调用中修改 set
时.
这是修改后的代码:
# scratch_1.py
import random
import string
import matplotlib.pyplot as plt
import plotly.graph_objects as go
target = "ab"
letras = string.ascii_lowercase
def generate_random_candidate(tried_candidates):
while True:
intento = random.choice(letras) + random.choice(letras)
if intento not in tried_candidates:
tried_candidates.add(intento)
return intento
def generate_children(parent, tried_candidates):
hijos = []
while True:
intento = parent[0] + random.choice(letras)
if intento not in tried_candidates:
hijos.append(intento)
break
while True:
intento = random.choice(letras) + parent[1]
if intento not in tried_candidates:
hijos.append(intento)
break
return hijos
def g():
tried_candidates = set()
population_size = 10
population = []
for _ in range(population_size):
population.append(generate_random_candidate(tried_candidates))
contador = 1
while True:
scores = []
for candidate in population:
scores.append(evaluate_candidate(candidate))
children = []
Flag = False
for i, score in enumerate(scores):
if score == 2:
Flag = True
break
if score == 1:
x = generate_children(population[i], tried_candidates)
tried_candidates.update(x)
children.extend(x)
if len(children) < population_size:
new_candidates = []
for _ in range(population_size - len(children)):
y = generate_random_candidate(tried_candidates)
tried_candidates.add(y)
new_candidates.append(y)
children.extend(new_candidates)
population = children
else:
meter = children[population_size:]
population = children[:population_size]
tried_candidates.difference_update(meter)
found = False
for candidate in population:
if evaluate_candidate(candidate) == 2 or Flag:
found = True
return contador
contador += 1
def evaluate_candidate(candidate):
score = 0
if candidate[0] == target[0]:
score += 1
if candidate[1] == target[1]:
score += 1
return score
resultados = []
for i in range(100000):
resultados.append(g())
希望这对你有一点帮助。