0

在玩输入验证时,特别检查提供的数据是否具有指定的所有必需属性,并丢弃我不想要的属性,我做了这样的事情:

>>> input = {'v1': 'val1', 'a2':'val2', 'a3':'val3'} 
>>> print input
{'v1': 'val1', 'a3': 'val3', 'a2': 'val2'}
>>> goodkeys = ['a2', 'a3']
>>> print goodkeys
['a2', 'a3']
>>> output = {}
>>> for a in goodkeys:    
...   output[a] = input[a]
... 
>>> 
>>> print output
{'a3': 'val3', 'a2': 'val2'}

这当然有效。但我突然想到,也许可以用一种更蟒蛇的方式来做到这一点。我试过了:

>>> output = {}
>>> print output
{}
>>> output = { a:v for a in goodkeys for v in input[a] }
>>> print output
{'a3': '3', 'a2': '2'}
>>> 

有半秒钟我认为有效,然后我意识到这些值是错误的。有没有漂亮的 Python 方法?发生了什么,Python 是从哪里得到这些值的?

4

3 回答 3

3

您可以使用字典视图对象

goodkeys = {'a2', 'a3'}
output = {a: input[a] for a in input.viewkeys() & goodkeys}

哪里goodkeys是集合;dict.viewkeys()产生一个反映字典内容的类集合对象,并& goodkeys产生这些键和goodkeys集合之间的交集。这样,您只能生成既在输入字典中又在一组好键中的键。

您创建了一个这样的嵌套循环:

for a in goodkeys:
    for v in input[a]:
        # v is a single character in the string value

演示:

>>> input = {'v1': 'val1', 'a2':'val2', 'a3':'val3'} 
>>> goodkeys = {'a2', 'a3'}
>>> {a: input[a] for a in input.viewkeys() & goodkeys}
{'a3': 'val3', 'a2': 'val2'}

由于input[a]是一个字符串,因此您的内部循环产生了每个值的单个字符:

>>> for a in goodkeys:
...     for v in input[a]:
...         print a, v
... 
a3 v
a3 a
a3 l
a3 3
a2 v
a2 a
a2 l
a2 2

键必须是唯一的,因此对于a2, , 和 中的一个v被挑选出来a,而其他的则被丢弃。字典理解首先设置,然后设置,等等,最后只保留在输出中。l2'a2': 'v''a2': 'a''a2': '2'

你不需要使用那个内循环;你本可以坚持:

{a: input[v] for a in goodkeys}

除了如果有任何goodkeys不在其中的键,input你会得到一个KeyError. 字典视图方法巧妙地回避了这个问题。

于 2014-12-12T16:20:47.863 回答
0

你可能想多了。试着改变

output = { a:v for a in goodkeys for v in input[a] }

简单地...

output = { a:input[a] for a in goodkeys }
于 2014-12-12T16:23:33.723 回答
0
output = { a:input[a] for a in goodkeys }

您的第二个for迭代字符串值的字符。

于 2014-12-12T16:20:44.513 回答