2013-03-13 88 views
2

我有一个这样的名单:如何列表值与字典键比较并做它的一个新的字典使用python

lis = ['Date', 'Product', 'Price'] 

我想它比较:

dict = {'Date' : '2013-05-01', 'Salary' : '$5000', 'Product' : 'Toys', 'Price' : '$10', 'Salesman' : 'Smith'} 

我想将每个列表项与字典键进行比较并制作新的字典。
我曾尝试是:

n = {} 
for k,v in dict.items(): 
    for i in lis: 
     if i==k: 
      n[k] = v 

输出:

n = {'Date' : '2013-05-01', 'Product' : 'Toys', 'Price' : '$10'} 

这工作,但我想通过发电机来做到这一点 - 有人可以帮助我做到这一点?

+7

不要调用你的'dict''dict'它会影响Python中的'dict',用'd'代替。 – 2013-03-13 12:29:17

回答

8

款待lis为一组,而不是,所以你可以使用dictionary views和路口:

# python 2.7: 
n = {k: d[k] for k in d.viewkeys() & set(lis)} 

# python 3: 
n = {k: d[k] for k in d.keys() & set(lis)} 

或者你可以使用一个简单的字典的理解与对d一个in测试:

# python 2.6 or older: 
n = dict((k, d[k]) for k in lis if k in d) 

# python 2.7 and up: 
n = {k: d[k] for k in lis if k in d} 

这假定lis中的所有值都不是d;如果它们总是存在,则可以放弃if k in d测试。

针对您的特殊情况下,第二种形式是相当快了很多:

>>> from timeit import timeit 
>>> timeit("{k: d[k] for k in d.viewkeys() & s}", 'from __main__ import d, lis; s=set(lis)') 
2.156520128250122 
>>> timeit("{k: d[k] for k in lis if k in d}", 'from __main__ import d, lis') 
0.9401540756225586 
+1

如果在k中,{k:d [k]如果k中的d}比'{k:v for k,v in d.items()if k in lis}'更有效率?这样,'in'检查总是针对字典(摊销O(1))而不是列表(O(n)) – Claudiu 2013-03-13 12:38:35

+0

@Claudiu进行:事实上,这可能会更好。更新。 – 2013-03-13 12:39:14

2
filtered_dict = dict((k, original_dict[k]) for k in lis if k in original_dict) 

或者,如果你有2.7+:

filtered_dict = {k: original_dict[k] for k in lis if k in original_dict} 

如果你想使用一个发电机:

item_generator = ((k, original_dict[k]) for k in lis if k in original_dict) 

发生器将产生(key, value)双。