[英]Efficiently Compacting a List of Tuples to a Dictionary of Lists in Python?
我感興趣的是找到一種更有效的方法( 代碼復雜性,速度,內存使用,理解,生成器 ),以減少兩個元素元組的列表,其中第一個元素可以在元素之間重復,從而簡化為列表字典。
from copy import deepcopy
a = [('a', 'cat'), ('a', 'dog'), ('b', 'pony'), ('c', 'hippo'), ('c','horse'), ('d', 'cow')]
b = {x[0]: list() for x in a}
c = deepcopy(b)
for key, value in b.items():
for item in a:
if key == item[0]:
c[key].append(item[1])
print(a)
print(c)
[('a','cat'),('a','dog'),('b','pony'),('c','hippo'),('c','horse') ,('d','cow')]
{'a':['cat','dog'],'b':['pony'],'c':['hippo','horse'],'d':['cow']}
from collections import defaultdict
from itertools import groupby
from operator import itemgetter
import timeit
timings = dict()
def wrap(func, *args, **kwargs):
def wrapped():
return func(*args, **kwargs)
return wrapped
a = [('a', 'cat'), ('a', 'dog'), ('b', 'pony'), ('c', 'hippo'), ('c','horse'), ('d', 'cow')]
# yatu's solution
def yatu(x):
output = defaultdict(list)
for item in x:
output[item[0]].append(item[1])
return output
# roseman's solution
def roseman(x):
d = defaultdict(list)
for key, value in a:
d[key].append(value)
return d
# prem's solution
def prem(a):
result = {k: [v for _,v in grp] for k,grp in groupby(a, itemgetter(0))}
return result
# timings
yatus_wrapped = wrap(yatu, a)
rosemans_wrapped = wrap(roseman, a)
prems_wrapped = wrap(prem, a)
timings['yatus'] = timeit.timeit(yatus_wrapped, number=100000)
timings['rosemans'] = timeit.timeit(rosemans_wrapped, number=100000)
timings['prems'] = timeit.timeit(prems_wrapped, number=100000)
# output results
print(timings)
{'yatus':0.171220442,'rosemans':0.153767728,'prems':0.22808025399999993}
羅斯曼的解決方案幾乎是最快的,謝謝。
這可以通過使用defaultdict的單個循環來完成:
from collections import defaultdict
d = defaultdict(list)
for key, value in a:
d[key].append(value)
您可以使用defaultdict
:
from collections import defaultdict
a = [('a', 'cat'), ('a', 'dog'), ('b', 'pony'), ('c', 'hippo'), ('c','horse'), ('d', 'cow')]
output = defaultdict(list)
for item in a:
output[item[0]].append(item[1])
這種方法將需要較少的空間(只需要a
和output
),並且具有更好的運行時(線性運行時復雜性,因為它a
一次迭代並將每個元素添加到output
字典中-插入字典的時間是固定的)。
您可以使用itertools.groupby
首先將項目分組,然后根據需要合並它們
>>> from itertools import groupby
>>> from operator import itemgetter
>>> {k: [v for _,v in grp] for k,grp in groupby(a, itemgetter(0))}
{'a': ['cat', 'dog'], 'b': ['pony'], 'c': ['hippo', 'horse'], 'd': ['cow']}
如果輸入不總是按排序順序排序
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.