为什么此代码会抛出" StopIteration":
stub_generator = (x for x in range(5))
stub_dict = {}
stub_dict[next(stub_generator)] = list(stub_generator)
这有用吗?
stub_generator = (x for x in range(5))
stub_dict = {}
temp_1 = next(stub_generator)
temp_2 = list(stub_generator)
stub_dict[temp_1] = temp_2
答案 0 :(得分:3)
这种行为是因为两件事:
赋值语句的右侧在左侧之前进行评估。
生成器对象只能迭代一次。
进一步解释,执行此代码时:
stub_dict[next(stub_generator)] = list(stub_generator)
这一部分:
list(stub_generator)
将在此部分之前进行评估:
stub_dict[next(stub_generator)]
此外,将stub_generator
置于list
将导致生成器完全迭代并因此耗尽。之后评估next(stub_generator)
时会引发StopIteration
异常,因为stub_generator
现在为空。
但这段代码不同:
temp_1 = next(stub_generator)
temp_2 = list(stub_generator)
在执行next(stub_generator)
之前执行list(stub_generator)
。这意味着,stub_generator
在转换为列表时仍会包含一些项目。
答案 1 :(得分:1)
根据language reference for assignment statements,
assignment_stmt ::= (target_list "=")+ (expression_list | yield_expression)
赋值语句计算表达式列表(请记住,这可以是单个表达式或以逗号分隔的列表,后者产生元组)并将单个结果对象从左到右分配给每个目标列表。
因此,首先评估右侧的表达式。因此,首先执行list(stub_generator)
并耗尽生成器,然后您正在执行next(stub_generator)
,它会尝试迭代已经耗尽的生成器。这就是StopIteration
被提出的原因。