【问题标题】:Collecting values from a Python dictionary with list of keys从带有键列表的 Python 字典中收集值
【发布时间】:2015-05-15 02:37:36
【问题描述】:
Dict = {'w1': 56, 'w2': 19, 'w3': 77, 'w4': 45, 'w5': 31}
myWords = ['w1','w4','w5']

OutputList=[]
for items in myWords:
    tmps = Dict[items]
    OutputList.append(tmps)

我的问题是,我们能否使用 for 循环,从具有特定列表(“myWord”)的字典中收集值(输出)?

【问题讨论】:

  • 为什么要避免使用 for 循环?
  • 不要使用带有大写名称的变量! 不要重用只改变大小写的内置函数的名称!
  • 不确定如何你管理它,但看起来你发现了一个错误。您通常不能将多个答案标记为“已接受”(您应该选择对您帮助最大的答案)。然而,我们在这里,有两个答案被标记为已接受。见How did this question get two accepted answers?

标签: python function dictionary key


【解决方案1】:

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

OutputList = map(Dict.get, myWords)

【讨论】:

  • 嗨,何塞。如果 dict 很大说 len(Dict.keys()) = 1048576,而我的列表大约 10000,那么 map 函数与 For 循环相比可以提高性能?
  • @GregHewgill 你能帮我解决这个问题吗,因为我不知道
  • @ChinLim,试试看 - timeit
  • 如果字典中不包含该元素,则此方法将在 OutputList 中包含 None
  • @Javier,是的....你是对的,添加None ....在这种情况下是更好的 chepner 解决方案
【解决方案2】:

您可以使用列表推导

OutputList = [Dict[x] for x in myWords]

【讨论】:

  • 理解中是否隐含了 (for) 循环?
  • 是的,无论哪种方式,您都必须遍历列表,如果可能,在 Python 中最好在迭代时使用 map 和内置函数,因为它们是在 C 中实现的
  • @wwii:列表解析语法包含关键字for,并不意味着它是一个“for循环”。
  • @Javier 有时理解比使用 map 和其他内置函数更有效。
  • @ChinLim:这两个选项的相对性能取决于您的环境和数据。我建议您测量每个的性能,以确定您的系统上哪个是最快的。
【解决方案3】:

这就是operator.itemgetter 的用途:

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

【讨论】:

  • 嗨,Chepner 如果字典很大,说 len(Dict.keys()) = 1048576,而我的列表大约 10000,那么与 For 循环相比,operator.itemgetter 可以提高性能?
  • 您必须对其进行测试,但我想itemgetter 应该更快。
  • 嘿chepner,很好的答案。然而一个小建议..添加一个链接到docs,因为它真的会帮助那些不知道operator.itemgetter的人
  • 好建议。我添加了指向 Python 2 文档的链接;我认为Python 3 version 没有任何区别。
  • @chepner 你真的有一个列表结果吗,就像代码中显示的那样?我认为 itemgetter 返回一个元组。
【解决方案4】:

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

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 2.7,打印:

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

Python 3.4:

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

PyPy:

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

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

您还可以看到看起来花哨的东西并不是那么好。

过早的优化是万恶之源

【讨论】:

  • 有趣的是,itemgetter 在 PyPy 中实际上更糟糕,而不仅仅是优化不足。
【解决方案5】:
l = ['a', 'b', 'c'] 
d = { 'a': 1, 'b': 2}
result = map(lambda x: d[x], filter(d.get, l))
print result #[1, 2]

【讨论】:

  • 嗨哈维尔。谢谢。上面例子中的“lamda x: d[x]”做了什么?在 python 帮助文件中的 map (function, sequence) 中,这个建议是否可以在巨大的字典和大列表上工作.. Thanjs
  • 你能解释为什么投票否决吗?这用不同的方法回答了这个问题
  • 您正在尝试获取字典的值,Map 将遍历过滤器的结果,并返回一个列表,其中包含应用于过滤器的每个元素的第一个参数(lambda 函数) .在 Python shell 中尝试一下,这将产生您所期望的结果
  • 嗨,哈维尔..你的回答很有用..我可以知道投票反对吗?谢谢。
  • 这实际上是行不通的。如果 dict d 中有任何不正确的值,它将被过滤器过滤掉,因为 'get' 正在返回该值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-27
  • 2014-03-14
  • 2021-09-26
  • 1970-01-01
  • 2015-12-21
  • 2021-12-09
  • 1970-01-01
相关资源
最近更新 更多