我想将两个已排序的列表合并到一个新的排序列表中,但我想在新列表中包含标签,以查看哪个列表是每个值的来源。
到目前为止,这是我的代码:
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。有更快的方法吗?因为我的名单会很长(数十万)
答案 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()
。