itertools.chain
ジェネレーターを作成するだけなので、リストの代わりにジェネレーターを使用する必要がない場合は、生成するのに一定の時間がかかりますが、各要素にアクセスするときにコストを支払います。それ以外の場合list_a[0:0] = list_b
は、約6倍高速ですlist_a = list_b + list_a
私はそれlist_a = list_b + list_a
が最も読みやすい選択だと思います、そしてそれはすでにかなり速いです。
append()
ループでの使用についておっしゃった2つの方法for
は非常に遅いので、わざわざそれらを含めませんでした。
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
次のコードを使用して、16GBの2133MHzLPDDR3RAMを搭載した1.6GHzデュアルコアIntelCorei5でPython3.7.5を実行しました。
from timeit import timeit
import random
import matplotlib.pyplot as plt
num_data_points = 1000
step = 10
methods = [
# ordered from slowest to fastest to make the key easier to read
# """for item in list_a: list_b.append(item); list_a = list_b""",
# """for item in list_b: list_a.insert(0, item)""",
# "list_a = list(itertools.chain(list_b, list_a))",
"list_a = list_b + list_a",
"list_a[0:0] = list_b",
"list_a = itertools.chain(list_b, list_a)",
]
x = list(range(0, num_data_points * step, step))
y = [[] for _ in methods]
for i in x:
list_a = list(range(i))
list_b = list(range(i))
random.shuffle(list_a)
random.shuffle(list_b)
setup = f"list_a = {list_a}; list_b = {list_b}"
for method_index, method in enumerate(methods):
y[method_index].append(timeit(method, setup=setup, number=30))
print(i, "out of", num_data_points * step)
ax = plt.axes()
for method_index, method in enumerate(methods):
ax.plot(x, y[method_index], label=method)
ax.set(xlabel="number of elements in both lists", ylabel="time (s) (lower is better)")
ax.legend()
plt.show()