多种列表拼接方法及其性能

2024-03-29 12:02:07 发布

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

我正在研究一个算法,在这方面,我们正在努力编写代码中的每一行,这样它就为最终的代码增加了一个良好的性能。你知道吗

在一种情况下,我们必须添加列表(特别是两个以上的列表)。我知道一些连接两个以上列表的方法,我也看过StackOverflow,但是没有一个答案能说明这个方法的性能。你知道吗

有谁能告诉我们,我们可以用什么方法把两个以上的列表连接起来,以及它们各自的性能?你知道吗

编辑:列表的大小从2到13不等(具体来说)。 编辑重复:我一直特别要求的方式,我们可以添加和他们尊重的问题,在重复的问题,它仅限于4种方法


Tags: 方法答案代码算法编辑列表方式情况
3条回答

我做了一些简单的测量,以下是我的结果:

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))

如果您要将数量可变的列表串联在一起,那么您的输入将是一个列表列表(或一些等效的集合)。性能测试需要考虑到这一点,因为您将无法执行类似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])

有多种方法可以用来连接两个以上的列表。你知道吗

假设我们有三张单子

a = ['1']
b = ['2']
c = ['3']

然后,在python中连接两个或多个列表

(一) 你可以简单地连接它们

 output = a + b + c

(二) 你也可以用列表理解

res_list = [y for x in [a,b,c] for y in x] 

(三) 你也可以用extend()来做

a.extend(b)
a.extend(c)
print(a)

(四) 你也可以用*运算符

res = [*a,*b,*c]

为了计算性能,我使用了python中的timeit模块。你知道吗

以下方法的性能如下:

4th method < 1st method < 3rd method < 2nd [method on the basis of time]

这意味着如果您要使用“*运算符”来连接两个以上的列表,那么您将获得最佳性能。你知道吗

希望你得到你想要的。你知道吗

Edit::显示所有方法性能的图像(使用timeit计算)

enter image description here

相关问题 更多 >