jul*_*e64 5 python list-comprehension generator
我试图将相同西装(颜色)的卡片组合在一起并在发生器内排名,并将这些发生器存储在列表理解中.
我提出的解决方案除了所有发生器包含完全相同的卡之外.知道为什么吗?
这是代码
deck=range(52)
gens=[(i for i in deck if i%13==v) for v in range(13)]
Run Code Online (Sandbox Code Playgroud)
基于此,我希望例如:
gens[1].next()
1
gens[1].next()
14
gens[10].next()
10
gens[10].next()
23
Run Code Online (Sandbox Code Playgroud)
但相反,我得到了
gens[1].next()
12
gens[1].next()
25
gens[1].next()
38
Run Code Online (Sandbox Code Playgroud)
并且列表中的所有生成器返回相同的结果..
问题是v生成器表达式中的名称引用v列表推导中的该变量.因此,当您的生成器表达式实际运行的代码(当您调用时next),它会查看变量v并查看值12,无论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)]
Run Code Online (Sandbox Code Playgroud)
因为我们定义了一个函数,所以名称v可以存在于自己的命名环境中,因此保持不变.
如果你真的想要,你可以在一行中做到这一点:
gens = [(lambda v: (i for i in deck if i % 13 == v))(v) for v in range(13)]
Run Code Online (Sandbox Code Playgroud)
如果将其转换为等效的嵌套循环,则可以更轻松地查看范围界定问题:
gens = []
for v in range(13):
def gen():
for i in deck:
if i%13 == v:
yield i
gens.append(gen())
Run Code Online (Sandbox Code Playgroud)
你最终得到13个生成器,所有生成器都绑定到v12 的相同值.
因此,此处的解决方案与任何其他范围问题中的解决方案相同:您需要使用其中的内容创建新范围v.最简单的方法是创建一个新函数:
gens = [(lambda x: (i for i in deck if i%13==x)(v) for v in range(13)]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
710 次 |
| 最近记录: |