按值加入列表

时间:2015-06-03 22:32:29

标签: python performance list for-loop dictionary

是否有一种基于公共值在python中合并两个元组列表的有效方法。目前,我正在做以下事情:

name = [
         (9, "John", "Smith"),
         (11, "Bob", "Dobbs"),
         (14, "Joe", "Bloggs")
         ]

occupation = [
              (9, "Builder"),
              (11, "Baker"),
              (14, "Candlestick Maker")
              ]

name_and_job = []

for n in name:
    for o in occupation:
        if n[0] == o[0]:
            name_and_job.append( (n[0], n[1], n[2], o[1]) )


print(name_and_job)

返回:

[(9, 'John', 'Smith', 'Builder'), (11, 'Bob', 'Dobbs', 'Baker'), (14, 'Joe', 'Bloggs', 'Candlestick Maker')]

虽然这段代码适用于小型列表,但对于包含数百万条记录的较长列表来说,令人难以置信地慢。有没有更有效的方法来写这个?

编辑第一列中的数字是唯一的。

编辑稍微修改了@John Kugelman的代码。添加了一个get(),以防名称字典在职业字典中没有匹配的密钥:

>>>> names_and_jobs = {id: names[id] + (jobs.get(id),) for id in names}
>>>> print(names_and_jobs)
{9: ('John', 'Smith', None), 11: ('Bob', 'Dobbs', 'Baker'), 14: ('Joe', 'Bloggs', 'Candlestick Maker')}

2 个答案:

答案 0 :(得分:5)

使用词典代替平面列表。

names = {
    9:  ("John", "Smith"),
    11: ("Bob", "Dobbs"),
    14: ("Joe", "Bloggs")
} 

jobs = {
    9:  "Builder",
    11: "Baker",
    14: "Candlestick Maker"
}

如果您需要将它们转换为此格式,您可以执行以下操作:

>>> {id: (first, last) for id, first, last in name}
{9: ('John', 'Smith'), 11: ('Bob', 'Dobbs'), 14: ('Joe', 'Bloggs')}
>>> {id: job for id, job in occupation}
{9: 'Builder', 11: 'Baker', 14: 'Candlestick Maker'}

然后将这两者合并是一块蛋糕。

names_and_jobs = {id: names[id] + (jobs[id],) for id in names}

答案 1 :(得分:1)

from collections import OrderedDict
from itertools import chain

od = OrderedDict()


for ele in chain(name,occupation):
    od.setdefault(ele[0], []).extend(ele[1:])


print([[k]+val for k,val in od.items()])

[[9, 'John', 'Smith', 'Builder'], [11, 'Bob', 'Dobbs', 'Baker'], [14, 'Joe', 'Bloggs', 'Candlestick Maker']]

如果您希望按名称中的数据排序数据,那么您需要使用OrderedDict,因为正常的dicts是无序的。

您还可以在循环中添加数据,创建所需的元组,然后只调用od.values来获取元组列表:

from collections import OrderedDict
from itertools import chain

od = OrderedDict()

for ele in chain(name, occupation):
    k = ele[0]
    if k in od:
        od[k] = od[k] + ele[1:]
    else:
       od[k] = ele

print(od.values())
[(9, 'John', 'Smith', 'Builder'), (11, 'Bob', 'Dobbs', 'Baker'), (14, 'Joe', 'Bloggs', 'Candlestick Maker')]