簡體   English   中英

有效地將元組列表壓縮為Python中的列表字典?

[英]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])

這種方法將需要較少的空間(只需要aoutput ),並且具有更好的運行時(線性運行時復雜性,因為它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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM