缺乏对多变量赋值的理解Python

时间:2012-08-03 07:57:32

标签: python list tuples list-comprehension

我是Python的新手(以Java为基础)。我在第3章中发现了Dive Into Python本书Multi-Variable Assignment。也许你们中的一些人可以帮助我理解这段代码中发生的事情:

>>> params = {1:'a', 2:'b', 3:'c'}
>>> params.items() # To display list of tuples of the form (key, value).
[(1, 'a'), (2, 'b'), (3, 'c')]

>>> [a for b, a in params.items()] #1
['a', 'b', 'c']
>>> [a for a, a in params.items()] #2
['a', 'b', 'c']
>>> [a for a, b in params.items()] #3
[ 1 ,  2 ,  3 ]
>>> [a for b, b in params.items()] #4
[ 3 ,  3 ,  3 ]

到目前为止我所理解的是#1#2具有相同的输出,它显示了元组的值。 #3显示元组的键,#4只显示元组列表中的最后一个键。

我不理解上面每个案例使用变量a和变量b

  1. a for b, a ... - >显示值
  2. a for a, a ... - >显示值
  3. a for a, b ... - >显示键
  4. a for b, b ... - >显示最后一个键
  5. 任何人都能详细说明上述每个案例的循环流程吗?

3 个答案:

答案 0 :(得分:8)

你在那里使用的列表理解大致翻译如下:

[a for b, a in params.items()]

变为

result = []
for item in params.items():
    b = item[0]
    a = item[1]
    result.append(a)

[a for a, a in params.items()]

变为

result = []
for item in params.items():
    a = item[0]
    a = item[1] # overwrites previous value of a, hence this yields values, 
                # not keys
    result.append(a)

[a for a, b in params.items()]

变为

result = []
for item in params.items():
    a = item[0]
    b = item[1]
    result.append(a)

[a for b, b in params.items()]

变为

result = []
for item in params.items():
    b = item[0]
    b = item[1]
    result.append(a) # note use of a here, which was not assigned

最后一个是特别的。它之所以有效,是因为您在前一个语句中使用了变量a,并且分配给它的最后一个值是3。如果您先执行此语句,则会收到错误。

答案 1 :(得分:6)

在所有四种情况下,元组中的名称按顺序从序列中绑定到对中的每个元素。第四个例子是Python 2.x中的(错误)行为的一个例子;该名称被绑定到它拥有的最后一个对象,甚至在LC之外。此行为在3.x中已得到修复。

>>> [x for x in (1, 2, 3)]
[1, 2, 3]
>>> x
3

3>> [x for x in (1, 2, 3)]
[1, 2, 3]
3>> x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined

答案 2 :(得分:3)

元组只是将变量打包在一起。当你打电话

时,你得到这些对
params.items()

正如你在评论中写的那样。

要打开一个元组,你需要做的就是:

>>> a, b = (2, 3)
>>> a
2
>>> b
3

使用列表推导时也是如此。

>>> [a for a, b in [(2, 3), (4, 5)]]
[2, 4]

这里取出列表中每个元组的元组的第一个元素。在你的情况下使用params列表而不是我的短列表是#1。

如果你改为写

>>> [b for a, b in [(2, 3), (4, 5)]]
[3, 5]

你得到第二个元素。这相当于你的#3。

另外两个并没有多大意义。在#2你有

>>> [a for a, a in [(2, 3), (4, 5)]]
[3, 5]
>>> a,a = (2,3)
>>> a
3

它只是让第一个第一个然后直接用每个解包中的第二个参数覆盖它。你可以用单个元组发生同样的事情。

最后#4只是绞尽脑汁。如果你还没有使用过一个变量,那么由于当时不存在这个变量就行不通。

>>> [a for b, b in [(2, 3), (4, 5)]]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined

我希望这能回答你的问题。