使用键列表从Python字典中收集值

使用键列表从Python字典中收集值,python,function,dictionary,key,Python,Function,Dictionary,Key,我的问题是,我们是否可以在不使用for循环的情况下,从具有特定列表(“myWord”)的词典中收集值(输出)?您可以使用列表理解: 或者,如果myWords包含字典Dict中的键,则使用map OutputList = [Dict[x] for x in myWords] 这是为了: 以下是几种不同方法的基准: >>> import operator >>> Dict = {'w1': 56, 'w2': 19, 'w3': 77, 'w4': 45, 'w

我的问题是,我们是否可以在不使用
for
循环的情况下,从具有特定列表(“myWord”)的词典中收集值(输出)?

您可以使用列表理解:


或者,如果
myWords
包含字典
Dict
中的键,则使用map

OutputList = [Dict[x] for x in myWords]
这是为了:


以下是几种不同方法的基准:

>>> import operator
>>> Dict = {'w1': 56, 'w2': 19, 'w3': 77, 'w4': 45, 'w5': 31}
>>> myWords = ['w1','w4','w5']
>>> operator.itemgetter(*myWords)(Dict)
[56, 45, 31]
对于Python 2.7,打印:

from __future__ import print_function
import timeit
from operator import itemgetter

def f1(d, l):
    '''map'''
    return list(map(d.get, l))

def f2(d, l):
    '''itemgetter'''
    return itemgetter(*l)(d)

def f3(d, l):
    '''list comprehension'''
    return [d[k] for k in l]

def f4(d, l):
    '''WRONG, but map and filter'''
    return list(map(lambda k: d[k], filter(d.get, l)))

def f5(d, l):
    '''simple for loop'''
    rtr=[]
    for e in l:
        rtr.append(d[e])
    return rtr  

def f6(d, l):
    '''CORRECTED map, filter '''    
    return list(map(lambda k: d[k], filter(d.__contains__, l))) 

if __name__ == '__main__':
    s=10000000
    d={'W{}'.format(k):k for k in range(s)} 
    l=['W{}'.format(x) for x in range(0,s,4)]

    times=[]                
    for f in (f1,f2,f3,f4,f5,f6):
        times.append((f.__doc__, timeit.timeit('f(d,l)', setup="from __main__ import f, d, l", number=10)))

    for e in sorted(times, key=itemgetter(1)):
         print('{:30}{:10.3f} seconds'.format(*e))
Python 3.4:

itemgetter                         4.109 seconds
list comprehension                 4.467 seconds
map                                5.450 seconds
simple for loop                    6.132 seconds
CORRECTED map, filter             11.283 seconds
WRONG, but map and filter         11.852 seconds
派比:

您可以看到,即使有一个与OP声明相似大小(1000000个元素)的字典,一个简单的“for”循环也可以与更高级的方法竞争。列表理解是非常有竞争力的

你也可以看到一些看起来很别致的东西并没有那么好



过早优化是万恶之源

理解中是否隐含(
for
)循环?是的,无论哪种方式,都必须循环列表,在Python中,如果可能,最好在迭代时使用map和内置函数,因为这些都是在C@wwii:仅仅因为列表理解语法包含关键字
for
,并不意味着它是一个“for循环”@Javier有时理解比使用
map
和其他内置项更有效。@ChinLim:这两个选项的相对性能取决于您的环境和数据。我建议您测量每个循环的性能,以确定哪个循环在您的系统上最快。为什么要避免使用for循环?不要使用大写名称的变量!不要重复使用只更改了大小写的内置名称!不确定您是如何管理的,但看起来您发现了一个bug。通常情况下,您不能将多个答案标记为“已接受”(您应该选择对您帮助最大的答案)。然而,我们在这里,有两个答案被标记为已接受。。你好,何塞。如果dict很大,则表示len(dict.keys())=1048576,而我的列表大约为10000,那么与For循环相比,map函数可以提高性能?@GregHewgill你能帮我解决这个问题吗,因为我没有know@ChinLim,试试看——如果元素不包含在输出列表中,这种方法将在输出列表中不包含任何元素dictionary@Javier对您是对的,添加
。。。。在这种情况下,chepner的解决方案更好吗?嗨,chepner如果dict很大,len(dict.keys())=1048576,我的列表大约为10000,那么操作符.itemgetter与For循环相比可以提高性能?你必须测试它,但我想
itemgetter
应该更快。嘿,chepner,回答得不错。然而,这是一个小小的建议。。一定要添加到的链接,因为它将真正帮助那些不了解
operator.itemgetter的人,这是一个很好的建议。我添加了一个到Python 2文档的链接;我不认为两者之间有任何区别。嗨,哈维尔。谢谢在上面的例子中,“lamdax:d[x]”是做什么的?在python帮助文件的映射(函数、序列)中,这个建议可以用于大型字典和大型列表。。你能解释一下为什么投票被否决吗?这就回答了这个问题,如果您试图获取字典的值,Map将循环过滤结果,并返回一个列表,其中第一个参数(lambda函数)应用于过滤结果中的每个元素。在Python shell中尝试一下,这将产生您所期望的结果。。你的回答很有用。。我可以知道否决票是指什么吗?谢谢。这实际上不起作用。如果dict d中有任何值不是真值,它将被filter过滤掉,因为'get'返回值。有趣的是,
itemgetter
在pypypy中实际上更糟糕,而不仅仅是优化程度更低。
>>> import operator
>>> Dict = {'w1': 56, 'w2': 19, 'w3': 77, 'w4': 45, 'w5': 31}
>>> myWords = ['w1','w4','w5']
>>> operator.itemgetter(*myWords)(Dict)
[56, 45, 31]
from __future__ import print_function
import timeit
from operator import itemgetter

def f1(d, l):
    '''map'''
    return list(map(d.get, l))

def f2(d, l):
    '''itemgetter'''
    return itemgetter(*l)(d)

def f3(d, l):
    '''list comprehension'''
    return [d[k] for k in l]

def f4(d, l):
    '''WRONG, but map and filter'''
    return list(map(lambda k: d[k], filter(d.get, l)))

def f5(d, l):
    '''simple for loop'''
    rtr=[]
    for e in l:
        rtr.append(d[e])
    return rtr  

def f6(d, l):
    '''CORRECTED map, filter '''    
    return list(map(lambda k: d[k], filter(d.__contains__, l))) 

if __name__ == '__main__':
    s=10000000
    d={'W{}'.format(k):k for k in range(s)} 
    l=['W{}'.format(x) for x in range(0,s,4)]

    times=[]                
    for f in (f1,f2,f3,f4,f5,f6):
        times.append((f.__doc__, timeit.timeit('f(d,l)', setup="from __main__ import f, d, l", number=10)))

    for e in sorted(times, key=itemgetter(1)):
         print('{:30}{:10.3f} seconds'.format(*e))
itemgetter                         4.109 seconds
list comprehension                 4.467 seconds
map                                5.450 seconds
simple for loop                    6.132 seconds
CORRECTED map, filter             11.283 seconds
WRONG, but map and filter         11.852 seconds
itemgetter                         5.196 seconds
list comprehension                 5.224 seconds
map                                5.923 seconds
simple for loop                    6.548 seconds
WRONG, but map and filter          9.080 seconds
CORRECTED map, filter              9.931 seconds
list comprehension                 4.450 seconds
map                                4.718 seconds
simple for loop                    5.962 seconds
itemgetter                         7.952 seconds
WRONG, but map and filter          8.962 seconds
CORRECTED map, filter              9.909 seconds