Python 2D 列表推导中传递引用的问题

3

请看这个字典的字典:

case_forms = {'plural': {'nominative': 'dni', 'locative': 'dniach'}, 
              'singular': {'instrumental': 'dniem', 'vocative': 'dzie\xc5\x84'}}

我希望能够获取所有可用作case_forms[a][b]的(a,b)键值对列表。

没问题,对吧?双重列表推导式。在Haskell中经常这样做:

[(number, case_name) for case_name in case_dict.keys() for number, case_dict in case_forms.items()]

然而,这并没有产生你所期望的结果:

[('plural', 'instrumental'),
 ('singular', 'instrumental'),
 ('plural', 'vocative'),
 ('singular', 'vocative')]

我想知道如何解决这个问题。无论如何巧妙地放置[:]似乎都不起作用。

2
这与传递引用有什么关系,Python 没有 传递引用? - juanpa.arrivillaga
我在2.7和3.5中都进行了直接复制粘贴;我发现case_dict在两个版本中都未定义。 - Prune
@Prune,那是不可能的,我刚刚做了完全相同的事情,在2.7.12上可以工作。 - Tom Busby
1
@TomBusby 因为在Python 2中,列表推导具有泄漏作用域,并且它没有使用您认为的case_dict,而是使用了先前推导(泄漏到外部作用域的)中的case_dict - juanpa.arrivillaga
1
我没有给你点踩,但是你没有提供可重现的例子,这就是为什么你被点踩的原因。无论如何,你尝试过开启一个新的会话并粘贴上述代码吗?你会得到一个 NameError - juanpa.arrivillaga
显示剩余11条评论
1个回答

2
这个怎么样:
[ (number, case_name) for number, case_dict in case_forms.items() for case_name in case_dict.keys() ]

编辑以引用@juanpa.arrivillaga有关我的示例行为奇怪的评论:

Python 2列表推导具有泄漏范围,它没有使用您认为的case_dict,而是使用了先前推导中泄漏到外部范围的case_dict

启动新的解释器会出现NameError


太棒了。非常感谢你。尽管如此,我仍然非常想了解为什么我的版本会产生错误的输出。 - Tom Busby
@TomBusby 因为你的理解顺序是相反的,所以出现了 NameError 错误。for 表达式的书写顺序与嵌套的 for 循环一样。 - juanpa.arrivillaga
“我将编辑引用@juanpa.arrivillaga并接受其为正确答案”。 - Tom Busby

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接