将两个列表与标签合并

时间:2014-05-07 23:44:41

标签: python list

我想将两个已排序的列表合并到一个新的排序列表中,但我想在新列表中包含标签,以查看哪个列表是每个值的来源。

到目前为止,这是我的代码:

l1 = [1, 40, 90, 104]
l2 = [5, 20, 70, 85, 230]
test = [(i, "l1") for i in l1 ] + [(i, "l2") for i in l2]
test.sort() 
print test

 [(1, 'l1'), (5, 'l2'), (20, 'l2'), (40, 'l1'), (70, 'l2'), (85, 'l2'), (90, 'l1'), (104, 'l1'), (230, 'l2')]

我正在使用Python 2.7.6。有更快的方法吗?因为我的名单会很长(数十万)

3 个答案:

答案 0 :(得分:3)

我通常使用itertools来做这种事情

import itertools
l1 = [1, 40, 90, 104]
l2 = [5, 20, 70, 85, 230]

test = zip(l1,itertools.repeat('li')) + zip(l2,itertools.repeat('l2'))

答案 1 :(得分:3)

l1 = [1, 40, 90, 104]
l2 = [5, 20, 70, 85, 230]

您可以选择标签方式:

ll1 = [(i, "l1") for i in l1]
ll2 = [(i, "l2") for i in l2]

import itertools
ll1i = zip(l1,itertools.repeat('l1'))
ll2i = zip(l2,itertools.repeat('l2'))

然后你可以解决它:

test = sorted(ll1 + ll2)

或者您可以使用heapq.merge

import heapq
test = list(heapq.merge(ll1, ll2))

或使用带有heapq的生成器:

ll1g = ((i, "l1") for i in l1)
ll2g = ((i, "l2") for i in l2)
test = list(heapq.merge(ll1g, ll2g))

N.B。:通常,使用列表理解或生成器在python中具有更好的性能 而不是使用itertools。默认的sort算法通常表现相当不错, 但如果列表已经排序,heapq.merge可能效果最好。

在2.5GHz Core2Quad上使用timeit和Python3,这里是基准测试(对于1000000重复的func):

使用itertools:

>>> timeit.Timer(lambda: heapq.merge(ll1i, ll2i)).repeat()
[0.4750211238861084, 0.4694850444793701, 0.46796107292175293]
>>> timeit.Timer(lambda: sorted(list(ll1i)+list(ll2i))).repeat()
[1.9459788799285889, 1.9470620155334473, 1.9455249309539795]

使用列表:

>>> timeit.Timer(lambda: sorted(ll1+ll2)).repeat()
[2.1228671073913574, 2.125030994415283, 2.1156458854675293]
>>> timeit.Timer(lambda: list(heapq.merge(ll1,ll2)) ).repeat()
[9.534330129623413, 9.518659830093384, 9.540029048919678]

使用发电机:

>>> timeit.Timer(lambda: sorted(itertools.chain(ll1g, ll2g))).repeat()
[1.2377429008483887, 1.2369508743286133, 1.2312331199645996]
>>> timeit.Timer(lambda: list(heapq.merge(ll1g,ll2g)) ).repeat()
[3.9007039070129395, 3.9058940410614014, 3.9031548500061035]

做自己的基准测试,并选择最适合您背景的解决方案!

*已编辑为包含结尾')'

答案 2 :(得分:1)

如果现有列表已经排序,您可以在生成器表达式上使用heapq.merge,将标记添加到列表项中。

import heapq

test = heapq.merge(((i, "l1") for i in l1), ((i, "l2") for i in l2))

test将是一个生成排序值/标记元组的生成器对象。如果您需要制作组合列表(而不是仅仅迭代值),您可以在生成器上调用list()