【问题标题】:builtins.ValueError: generator already executingbuiltins.ValueError:生成器已经在执行
【发布时间】:2022-10-30 15:51:28
【问题描述】:
f = open("test.txt", "r") 
try:
    open_file = f.read() 
finally:
    f.close()

satisfied = 0 
not_satisfied = 0 
distinct = ()
distinct = (variable for variable in open_file if not variable in distinct)
length = len(list(distinct))
for i in 2**length: #len(distinct_set) is the equivalent of 2**n
    binary = bin(i)
    binary_length = len(distinct)
    digits = f"binary:binary_length"
    true_false = ()
    for j in len(distinct): #See slide 24
        true_false.append(digits // 10**j % 10) 
        environments = zip(distinct,true_false)
        if eval(open_file,environments) == True:
            satisfied += 1
        else: 
            not_satisfied += 1            
print('Satisfied: ', satisfied, '; Not Satisfied: ', not_satisfied)

2行:

distinct = (variable for variable in open_file if not variable in distinct)
length = len(list(distinct))

给我一个“builtins.ValueError:生成器已经执行”有谁知道如何解决这个问题?

此外,如果有一种更 Pythonic 的方式来编写我的代码,那将非常有帮助 python新手,非常感谢任何帮助

【问题讨论】:

  • 请注意,distinct = (variable for variable in open_file if not variable in distinct) 无论如何都不会做你想做的事,因为分配给了distinct它通过检查每个值是否在distinct 中进行迭代。您可能需要一个集合并删除换行符,例如distinct = set(x.rstrip() for x in open_file.readlines()) 或稍短的版本distinct = {x.rstrip() for x in open_file.readlines()}
  • @Kemp:不,它是一个生成器表达式,所以首先发生赋值。然后list 调用开始实际执行,genexp 尝试对自己执行in 测试,从而触发异常。
  • @user2357112supportsMonica 啊,我对生成器表达式不太熟悉。我的解决方案仍然有效,即使我的诊断不正确:)
  • @Kemp:我认为我不能在字符串上使用 readlines() - 我得到一个 "builtins.AttributeError: 'str' object has no attribute 'readlines' 异常
  • 我的错,当我写的时候,我认为open_file 是文件,而不是文件中的内容。删除readlines()。应该把这个作为答案,然后我可以编辑掉我令人尴尬的疏忽:D

标签: python


【解决方案1】:

我将从解释开始。请参阅下面一节中的解决方案。

解释

发生这种情况是因为您的 distinct 生成器在其主体内部引用自身:if not variable in distinct

in 运算符在生成器上调用时会导致迭代生成器的所有元素。与此大致相似:

for item in generator:  # iteration happens here
    if variable == item:  # variable in distinct
        break

换句话说,这实际上是一个递归生成器,它“在被迭代时被迭代”。

当您调用list(distinct) 时,它会执行生成器,这就是为什么这是发生错误的行。上一行 (distinct = (…)) 只是一个赋值,在那里没有实际执行。

事实上,这是一个非常好的(也是现实生活中的!)自引用生成器示例。老实说,我没想到在合成代码sn-ps之外会发生这种情况,所以谢谢分享?

关于这个的详细解释,让我参考my other answer on Stack Overflow 与“生成器已经执行”/“异步生成器已经在运行”问题相关(参见“解释”和“同步生成器示例”部分)。

解析度

要解决您的特定用例,您应该使用 Python 的内置 set 类型:它专门用于存储唯一项目和有效率的检查它们在容器中的存在:

distinct = set(open_file)

set 将迭代 open_file 行并仅保留唯一的行。从 Python 3.6 开始,set 保留插入顺序。与dict 相同,因为它们依赖于哈希表的相同实现。虽然,此功能仅从 Python 3.7+ 开始记录,但在 Python 3.6 中这是实验性的,但仍受支持。

一个详细的代码示例,如果您需要 distinct 作为生成器:

def uniq(input_items):
    uniq_values = set()
    for variable in input_items:
        if variable not in uniq_values:
            yield variable
            uniq_values.add(variable)
distinct = uniq(open_file)  # generator with unique items

【讨论】:

    猜你喜欢
    • 2021-07-16
    • 2022-10-30
    • 2015-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-04
    • 1970-01-01
    相关资源
    最近更新 更多