我正在尝试将相同西装(颜色)的卡片组合在一起并在发生器内排名,并将这些发生器存储在列表理解中。
我提出的解决方案除了所有发生器包含完全相同的卡之外。知道为什么吗?
这是代码
deck=range(52)
gens=[(i for i in deck if i%13==v) for v in range(13)]
基于此,我希望例如:
gens[1].next()
1
gens[1].next()
14
gens[10].next()
10
gens[10].next()
23
但我得到了
gens[1].next()
12
gens[1].next()
25
gens[1].next()
38
列表中的所有生成器返回相同的结果..
答案 0 :(得分:7)
问题是,生成器表达式中的名称v
引用了列表推导中的变量v
。因此,当您的生成器表达式实际运行的代码时(当您调用next
时),它会查看变量v
并看到值12
,无论{{1}的值是什么是你创建生成器的时候。
一种解决方法:
v
因为我们定义了一个函数,所以名称deck = range(52)
def select_kth(v):
return (i for i in deck if i % 13 == v)
gens = [select_kth(v) for v in range(13)]
可以存在于自己的命名环境中,因此保持不变。
如果您真的想要,可以在一行中完成:
v
答案 1 :(得分:5)
如果将其转换为等效的嵌套循环,则可以更轻松地查看范围界定问题:
gens = []
for v in range(13):
def gen():
for i in deck:
if i%13 == v:
yield i
gens.append(gen())
最终你得到的13个生成器都绑定到v
,12的相同值。
因此,这里的解决方案与任何其他范围界定问题相同:您需要创建一个包含v
的新范围。最简单的方法是创建一个新函数:
gens = [(lambda x: (i for i in deck if i%13==x)(v) for v in range(13)]