我正在研究一种算法,因此,我们试图在代码中编写每一行,以便它为最终代码增加良好的性能。
在一种情况下,我们必须添加列表(特别是两个以上)。我知道一些方法可以连接两个以上的列表,我也查看过StackOverflow,但是没有一个答案可以说明该方法的性能。
任何人都可以证明,我们加入两个以上列表的方式以及各自的表现如何?
编辑:列表的大小从2到13(具体来说)不等。 编辑重复项:我一直在特别询问我们可以添加的方式及其受尊敬的问题,在重复问题中,它仅限于4种方法
答案 0 :(得分:5)
您可以通过多种方式加入两个以上的列表。
假设我们有三个列表,
a = ['1']
b = ['2']
c = ['3']
然后,用于在python中加入两个或多个列表,
1) 您可以简单地将它们串联起来,
output = a + b + c
2) 您也可以使用列表理解来做到这一点,
res_list = [y for x in [a,b,c] for y in x]
3) 您也可以使用extend()来完成它,
a.extend(b)
a.extend(c)
print(a)
4) 您也可以使用*运算符来完成此操作,
res = [*a,*b,*c]
为了计算性能,我使用了python中存在的timeit模块。
以下方法的性能是
第四方法<第一方法<第三方法<第二[基于 时间]
这意味着如果要使用“ *运算符”来连接两个以上的列表,那么您将获得最佳性能。
希望您能找到想要的东西。
编辑::该图显示了所有方法的性能(使用timeit计算)
答案 1 :(得分:2)
我做了一些简单的测量,这是我的结果:
import timeit
from itertools import chain
a = [*range(1, 10)]
b = [*range(1, 10)]
c = [*range(1, 10)]
tests = ("""output = list(chain(a, b, c))""",
"""output = a + b + c""",
"""output = [*chain(a, b, c)]""",
"""output = a.copy();output.extend(b);output.extend(c);""",
"""output = [*a, *b, *c]""",
"""output = a.copy();output+=b;output+=c;""",
"""output = a.copy();output+=[*b, *c]""",
"""output = a.copy();output += b + c""")
results = sorted((timeit.timeit(stmt=test, number=1, globals=globals()), test) for test in tests)
for i, (t, stmt) in enumerate(results, 1):
print(f'{i}.\t{t}\t{stmt}')
在我的机器上打印(AMD 2400G,Python 3.6.7):
1. 6.010000106471125e-07 output = [*a, *b, *c]
2. 7.109999842214165e-07 output = a.copy();output += b + c
3. 7.720000212430023e-07 output = a.copy();output+=b;output+=c;
4. 7.820001428626711e-07 output = a + b + c
5. 1.0520000159885967e-06 output = a.copy();output+=[*b, *c]
6. 1.4030001693754457e-06 output = a.copy();output.extend(b);output.extend(c);
7. 1.4820000160398195e-06 output = [*chain(a, b, c)]
8. 2.525000127207022e-06 output = list(chain(a, b, c))
答案 2 :(得分:2)
如果要将多个列表连接在一起,则输入将是列表列表(或等效的集合)。性能测试需要考虑到这一点,因为您将无法执行诸如list1 + list2 + list3之类的事情。
以下是一些测试结果(重复1000次):
option1 += loop 0.00097 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4]
option2 itertools.chain 0.00138 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4]
option3 functools.reduce 0.00174 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4]
option4 comprehension 0.00188 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4]
option5 extend loop 0.00127 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4]
option6 deque 0.00180 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4]
这将表明+ =遍历列表是最快的方法
产生它们的来源:
allLists = [ list(range(10)) for _ in range(5) ]
def option1():
result = allLists[0].copy()
for lst in allLists[1:]:
result += lst
return result
from itertools import chain
def option2(): return list(chain(*allLists))
from functools import reduce
def option3():
return list(reduce(lambda a,b:a+b,allLists))
def option4(): return [ e for l in allLists for e in l ]
def option5():
result = allLists[0].copy()
for lst in allLists[1:]:
result.extend(lst)
return result
from collections import deque
def option6():
result = deque()
for lst in allLists:
result.extend(lst)
return list(result)
from timeit import timeit
count = 1000
t = timeit(lambda:option1(), number = count)
print(f"option1 += loop {t:.5f}",option1()[:15])
t = timeit(lambda:option2(), number = count)
print(f"option2 itertools.chain {t:.5f}",option2()[:15])
t = timeit(lambda:option3(), number = count)
print(f"option3 functools.reduce {t:.5f}",option3()[:15])
t = timeit(lambda:option4(), number = count)
print(f"option4 comprehension {t:.5f}",option4()[:15])
t = timeit(lambda:option5(), number = count)
print(f"option5 extend loop {t:.5f}",option5()[:15])
t = timeit(lambda:option6(), number = count)
print(f"option6 deque {t:.5f}",option6()[:15])