Python - 将单键词典列表转换为单个词典

jay*_*elm 6 python dictionary list

我有一个单键词典列表.例如:

lst = [
    {'1': 'A'},
    {'2': 'B'},
    {'3': 'C'}
]
Run Code Online (Sandbox Code Playgroud)

我想简单地将其转换为普通字典:

dictionary = {
    '1': 'A',
    '2': 'B',
    '3': 'C'
}
Run Code Online (Sandbox Code Playgroud)

什么是最简洁/有效的方法?

Mar*_*ers 14

你可以使用reduce:

reduce(lambda r, d: r.update(d) or r, lst, {})
Run Code Online (Sandbox Code Playgroud)

演示:

>>> lst = [
...     {'1': 'A'},
...     {'2': 'B'},
...     {'3': 'C'}
... ]
>>> reduce(lambda r, d: r.update(d) or r, lst, {})
{'1': 'A', '3': 'C', '2': 'B'}
Run Code Online (Sandbox Code Playgroud)

或者你可以链接项目调用(Python 2):

from itertools import chain, imap
from operator import methodcaller

dict(chain.from_iterable(imap(methodcaller('iteritems'), lst)))
Run Code Online (Sandbox Code Playgroud)

Python 3版本:

from itertools import chain
from operator import methodcaller

dict(chain.from_iterable(map(methodcaller('items'), lst)))
Run Code Online (Sandbox Code Playgroud)

演示:

>>> from itertools import chain, imap
>>> from operator import methodcaller
>>> 
>>> dict(chain.from_iterable(map(methodcaller('iteritems'), lst)))
{'1': 'A', '3': 'C', '2': 'B'}
Run Code Online (Sandbox Code Playgroud)

或者使用词典理解:

{k: v for d in lst for k, v in d.iteritems()}
Run Code Online (Sandbox Code Playgroud)

演示:

>>> {k: v for d in lst for k, v in d.iteritems()}
{'1': 'A', '3': 'C', '2': 'B'}
Run Code Online (Sandbox Code Playgroud)

在这三个中,对于简单的3字典输入,字典理解最快:

>>> import timeit
>>> def d_reduce(lst):
...     reduce(lambda r, d: r.update(d) or r, lst, {})
... 
>>> def d_chain(lst):
...     dict(chain.from_iterable(imap(methodcaller('iteritems'), lst)))
... 
>>> def d_comp(lst):
...     {k: v for d in lst for k, v in d.iteritems()}
... 
>>> timeit.timeit('f(lst)', 'from __main__ import lst, d_reduce as f')
2.4552760124206543
>>> timeit.timeit('f(lst)', 'from __main__ import lst, d_chain as f')
3.9764280319213867
>>> timeit.timeit('f(lst)', 'from __main__ import lst, d_comp as f')
1.8335261344909668
Run Code Online (Sandbox Code Playgroud)

当您输入列表中的项目数增加到1000时,该chain方法会赶上:

>>> import string, random
>>> lst = [{random.choice(string.printable): random.randrange(100)} for _ in range(1000)]
>>> timeit.timeit('f(lst)', 'from __main__ import lst, d_reduce as f', number=10000)
5.420135974884033
>>> timeit.timeit('f(lst)', 'from __main__ import lst, d_chain as f', number=10000)
3.464245080947876
>>> timeit.timeit('f(lst)', 'from __main__ import lst, d_comp as f', number=10000)
3.877490997314453
Run Code Online (Sandbox Code Playgroud)

从现在开始,增加输入列表似乎并不重要; 这种chain()方法的速度提高了一小部分,但从未获得明显的优势.


iCo*_*dez 8

您可以使用字典理解:

>>> lst = [
...     {'1': 'A'},
...     {'2': 'B'},
...     {'3': 'C'}
... ]
>>> {k:v for x in lst for k,v in x.items()}
{'2': 'B', '3': 'C', '1': 'A'}
>>>
Run Code Online (Sandbox Code Playgroud)

  • 我认为这是最简单,最简单的. (2认同)