python:从另外两个列表创建组合列表

2024-10-06 11:39:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下两个清单:

list_of_dicts = [
    {'book': 1, 'title': 'novice'},
    {'book': 2, 'title': 'novice'},
    {'book': 3, 'title': 'novice'},
]
names = ['Johnny', 'Mike']

我想创建一个字典列表,表示这两个列表的组合,如下所示:

data = [
    {'book': 1, 'title': 'novice', name='Johnny'},
    {'book': 1, 'title': 'novice', name='Mike'},
    {'book': 2, 'title': 'novice', name='Johnny'},
    {'book': 2, 'title': 'novice', name='Mike'},
    {'book': 3, 'title': 'novice', name='Johnny'},
    {'book': 3, 'title': 'novice', name='Mike'},
]

到目前为止,我已经做到了这一点,但应该有更好的方法:

data = []
for d in list_of_dicts:
    for name in names:
        new_d = d.copy()
        new_d['name'] = name
        data.append(new_d)

我提出这个问题的原因是出于优化的考虑:在某些情况下,用例中的前两个列表可能非常庞大。你知道吗


Tags: ofnamein列表newfordatanames
1条回答
网友
1楼 · 发布于 2024-10-06 11:39:51

关于时间复杂性的注记

由于当前的算法已经在输出字典的数量中运行,并且您不能在少于O(k)的时间内构建k元素的列表,因此我们不能显著地提高它(在这个意义上,我们构造了一个具有不同时间复杂度的算法)。你知道吗

香草Python来增强

但是,我们可以使用实例列表理解和更有效的字典构造来稍微提高性能:

[{**d, 'name': name} for d in list_of_dicts for name in names]

如果我们将其与原始实现进行比较,我们可以得到以下基准:

old: 1.611422804009635
new: 1.3899883680278435 (-14%)

基准计划:

>>> def g():
...     data = []
...     for d in list_of_dicts:
...         for name in names:
...             new_d = d.copy()
...             new_d['name'] = name
...             data.append(new_d)
...     return data
... 
>>> def h():
...     return [{**d, 'name': name} for d in list_of_dicts for name in names]
... 
>>> timeit.timeit(g)
1.611422804009635
>>> timeit.timeit(h)
1.3899883680278435

使用生成器而不是列表

在处理大量输入时,最好使用生成器,因为这意味着我们从不构建完整的元素列表,而只在需要时计算下一个元素。这样做的好处有两个:如果我们减少了对生成器的迭代,我们就不会浪费计算从未使用过的字典的周期,而且我们还节省了内存,因为如果不再使用旧字典,它占用的内存就可以重用。缺点是,如果枚举所有元素,则生成器协议会浪费一些开销。通过使用圆括号()而不是方括号[],我们可以很容易地将列表理解转化为生成器:

({**d, 'name': name} for d in list_of_dicts for name in names)

大熊猫助推

如果每个字典都包含相同的键,我们也可以使用pandas。我们可以构造两个数据帧,然后将它们连接起来,如:

from pandas import DataFrame, merge

da = DataFrame(list_of_dicts)
db = DataFrame(names)
da['_tmpkey'] = db['_tmpkey'] = 1

result = merge(da, db, on='_tmpkey').drop('_tmpkey', axis=1).T.to_dict().values()

对于较小的数据集,Pandas通常会工作得较慢,但如果数据集较大,通常会导致显著的加速。你知道吗

相关问题 更多 >