2017-08-02 50 views
1

当使用扫描字典的理解表达式时,如果我知道字典的关键字很简单,那么可以将它们“展开”为命名变量?在理解中匹配字典关键元组项目

例如如果我有:

d = { ('car','blue') : 24, 
     ('car', 'red' ): 5, 
     ('plant',  'green'): 12, 
     ('box','blue'): 3 
} 

我知道我可以做

[d[key] for key in d.keys() if key[1]=='blue'] 

,并得到

[24, 3] 

但这失去了很多语义的,我想知道如果我能以某种方式做更像是:

[count for {(object,color):count} in d if color=='blue'] 

(我知道这是行不通的)。 此外,我不明白为什么最后表达式返回的错误是:

SyntaxError: can't assign to literal

+1

'[计数(对象,颜色),计数d.items()如果颜色== '蓝色']'? – vaultah

+1

'[d [物体,颜色]为物体,颜色为d如果颜色=='蓝色']' –

回答

3

我会去:

[count for (object, color), count in d.items() if color == 'blue']

为清晰的解决方案。

你所得到的错误是使用in关键字巨蟒试图将项目从d字典分配给{(object,color):count}是立即手段创建一个新的字典时,因为。相反,请使用(object, color), count,因为这是python扩展字典项目的方式。

+0

我会付出代价的。 ;) –

+0

太棒了,这正是我一直在寻找的。 所以我的3个错误:1)在拆包发生的变量周围不需要{}} 2)键和值部分应该用逗号分开而不是冒号3)用'in d.items()'而不是'在d'中。 – epeleg

1

你不能这么做,但如果你将你的钥匙“升级”到namedtuples,你可以关闭它。我使用'kind'作为named中第一项的名称,因为object是一个内置类型,尽管我们可以在这里安全地使用它,但我认为它会使代码有点混乱。

from collections import namedtuple 

d = { ('car', 'blue') : 24, 
     ('car', 'red'): 5, 
     ('plant', 'green'): 12, 
     ('box', 'blue'): 3 
} 

Thing = namedtuple('Thing', ('kind', 'color')) 
d = {Thing(*key): count for key, count in d.items()} 
print(d) 

lst = [count for key, count in d.items() if key.color == 'blue'] 
print(lst) 
lst = [count for key, count in d.items() if key.kind == 'car'] 
print(lst) 

输出

{Thing(kind='car', color='blue'): 24, Thing(kind='car', color='red'): 5, Thing(kind='plant', color='green'): 12, Thing(kind='box', color='blue'): 3} 
[24, 3] 
[24, 5] 

其实,你真的不需要 namedtuples,但我认为他们使它更好一点。 ;)

d = { ('car', 'blue') : 24, 
     ('car', 'red'): 5, 
     ('plant', 'green'): 12, 
     ('box', 'blue'): 3 
} 

lst = [count for (kind, color), count in d.items() if color == 'blue'] 
print(lst) 
-1

这是可能的。尝试:

[d.get((object,color)) for object,color in d.keys() if color == 'blue'] 

这将返回

[24, 3] 
+0

不需要'.get',因为密钥来自字典本身,所以它确信它们存在于那里。 –