2012-08-03 50 views
5

我是Python新手(以Java为基础)。我读了Dive Into Python的书,在第3章中我找到了关于Multi-Variable Assignment的书。也许你们中的一些可以帮助我了解此代码波纹管发生什么:对多变量赋值的理解不够Python

>>> 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 ... - >显示最后一个键

任何人都可以详细说明上述每种情况下的循环流程吗?

+0

你的问题是什么? – jtbandes 2012-08-03 08:00:02

+0

我想了解#1,#2,#3和#4中'a'和'b'变量的用法。 – Crazenezz 2012-08-03 08:01:02

+0

你对哪一个感到困惑? – dghubble 2012-08-03 08:04:20

回答

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。如果你先执行这个语句,你会得到一个错误。

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 
+1

关于2.x“泄漏”LC变量的好消息 – 2012-08-03 08:11:21

3

元组只是将变量包装在一起。当你致电

params.items() 

你可以在评论中写下你自己。

要解开一个元组,所有你需要做的是这样的:

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

同样的,当您使用列表解析完成。

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

这里a取出列表中每个元组的元组的第一个元素。这是使用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 

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