Pythonで2つのリストを連結するにはどうすればいいですか?
例:
listone = [1, 2, 3]
listtwo = [4, 5, 6]
期待される結果:
>>> joinedlist
[1, 2, 3, 4, 5, 6]
+
演算子を使用してそれらを組み合わせることができます。
listone = [1,2,3]
listtwo = [4,5,6]
mergedlist = listone + listtwo
出力:
>>> mergedlist
[1,2,3,4,5,6]
両方のリストの項目を単純に繰り返すジェネレータを作成することもできます。これにより、アイテムを新しいリストにコピーせずに、リスト(または反復可能なもの)をまとめて処理することができます。
import itertools
for item in itertools.chain(listone, listtwo):
# Do something with each list item
セットを使用して、一意の値のマージリストを取得できます
mergedlist = list(set(listone + listtwo))
Pythonの>= 3.5
代替:[*l1, *l2]
これは古い答えですが、PEP 448
を受け入れることで別の方法が導入されました。
追加の展開一般化という名前のPEPは、一般的に、Pythonでスター付きの*
式を使用する際の構文上の制限をいくつか軽減しました。それと、2つのリストを結合すること(任意のイテラブルに適用されます)は現在、以下でも行うことができます:
>>> l1 = [1, 2, 3]
>>> l2 = [4, 5, 6]
#unpack both iterables in a list literal
>>> joinedList = [*l1, *l2]
>>> print(joinedList)
[1, 2, 3, 4, 5, 6]
この機能Pythonの3.5
用に定義された _ 3.x
ファミリーの以前のバージョンにバックポートされていません。サポートされていないバージョンではSyntaxError
が発生します。
他のアプローチと同様に、これも対応するリストの要素のシャローコピーとして作成です。
このアプローチの upside は、実行するためにリストを実際には必要としないということです。繰り返し可能なものなら何でもかまいません。 PEPに記載されているように:
これは、
my_list + list(my_Tuple) + list(my_range)
のようにイテラブルをリストにまとめるためのより読みやすい方法としても役立ちます。これは現在は[*my_list, *my_Tuple, *my_range]
と同等です。
+
を追加すると、型が一致しないためTypeError
が発生します。
l = [1, 2, 3]
r = range(4, 7)
res = l + r
以下はそうではありません:
res = [*l, *r]
それは、最初にイテラブルの内容をアンパックしてから、その内容から単純にlist
を作成するからです。
extend
を追加するために list
を使用することもできます。
listone = [1,2,3]
listtwo = [4,5,6]
mergedlist = []
mergedlist.extend(listone)
mergedlist.extend(listtwo)
これは非常に簡単です、そしてそれは チュートリアル にも示されていたと思います。
>>> listone = [1,2,3]
>>> listtwo = [4,5,6]
>>>
>>> listone + listtwo
[1, 2, 3, 4, 5, 6]
この質問は2つのリストに参加することについて直接尋ねます。ただし、多数のリストに参加する方法を探している場合でも、検索はかなり高額です(ゼロリストに参加する場合も含む)。
私は最善の選択肢はリスト内包表記を使うことだと思います:
>>> a = [[1,2,3], [4,5,6], [7,8,9]]
>>> [x for xs in a for x in xs]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
ジェネレータも作成できます。
>>> map(str, (x for xs in a for x in xs))
['1', '2', '3', '4', '5', '6', '7', '8', '9']
オールドアンサー
このより一般的なアプローチを検討してください。
a = [[1,2,3], [4,5,6], [7,8,9]]
reduce(lambda c, x: c + x, a, [])
出力します:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
a
が[]
または[[1,2,3]]
の場合もこれは正しく機能します。
ただし、これはitertools
を使用するとより効率的に実行できます。
a = [[1,2,3], [4,5,6], [7,8,9]]
list(itertools.chain(*a))
あなたがlist
を必要とせず、単にイテラブルを必要とするなら、list()
を省略してください。
アップデート
コメントでパトリックコリンズによって提案された代替手段もあなたのために働くかもしれません:
sum(a, [])
次のように単純に+
または+=
演算子を使用できます。
a = [1, 2, 3]
b = [4, 5, 6]
c = a + b
または
c = []
a = [1, 2, 3]
b = [4, 5, 6]
c += (a + b)
また、マージリストの値を一意にしたい場合は、次の操作を実行できます。
c = list(set(a + b))
itertools.chain
関数が可変数の引数を受け取ることは注目に値します。
>>> l1 = ['a']; l2 = ['b', 'c']; l3 = ['d', 'e', 'f']
>>> [i for i in itertools.chain(l1, l2)]
['a', 'b', 'c']
>>> [i for i in itertools.chain(l1, l2, l3)]
['a', 'b', 'c', 'd', 'e', 'f']
反復可能オブジェクト(Tuple、list、generatorなど)が入力の場合は、from_iterable
クラスメソッドを使用できます。
>>> il = [['a'], ['b', 'c'], ['d', 'e', 'f']]
>>> [i for i in itertools.chain.from_iterable(il)]
['a', 'b', 'c', 'd', 'e', 'f']
Python 3.3以降では yield from を使用できます。
listone = [1,2,3]
listtwo = [4,5,6]
def merge(l1, l2):
yield from l1
yield from l2
>>> list(merge(listone, listtwo))
[1, 2, 3, 4, 5, 6]
あるいは、任意の数のイテレータをサポートしたい場合は、
def merge(*iters):
for it in iters:
yield from it
>>> list(merge(listone, listtwo, 'abcd', [20, 21, 22]))
[1, 2, 3, 4, 5, 6, 'a', 'b', 'c', 'd', 20, 21, 22]
2つのリストをソートされた形式でマージしたい場合は、merge
ライブラリのheapq
関数を使用できます。
from heapq import merge
a = [1, 2, 4]
b = [2, 4, 6, 7]
print list(merge(a, b))
プラス演算子(+
)を使用できない場合は、__add__
関数を使用できます。
listone = [1,2,3]
listtwo = [4,5,6]
result = list.__add__(listone, listtwo)
print(result)
>>> [1, 2, 3, 4, 5, 6]
あるいは、 dunders の使用が気に入らない場合は、operator
インポートを使用できます。
import operator
listone = [1,2,3]
listtwo = [4,5,6]
result = operator.add(listone, listtwo)
print(result)
>>> [1, 2, 3, 4, 5, 6]
これはもう少し読みやすいと主張できます。
より多くのリストのより一般的な方法としては、それらをリストの中に入れてitertools.chain.from_iterable()
を使うことができます。1 this answer に基づく関数は、ネストされたリストを平坦化するための最良の方法です。
>>> l=[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> import itertools
>>> list(itertools.chain.from_iterable(l))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
1. chain.from_iterable()
はPython 2.6以降で利用可能です。他のバージョンではchain(*l)
を使います。
2つの順序付きリストを複雑なソート規則でマージする必要がある場合は、次のコードのように自分でロールバックする必要があります(読みやすくするために単純なソート規則を使用します)。
list1 = [1,2,5]
list2 = [2,3,4]
newlist = []
while list1 and list2:
if list1[0] == list2[0]:
newlist.append(list1.pop(0))
list2.pop(0)
Elif list1[0] < list2[0]:
newlist.append(list1.pop(0))
else:
newlist.append(list2.pop(0))
if list1:
newlist.extend(list1)
if list2:
newlist.extend(list2)
assert(newlist == [1, 2, 3, 4, 5])
Pythonで2つのリストに参加する:
>>> a = [1, 2, 3, 4]
>>> b = [1, 4, 6, 7]
>>> c = a + b
>>> c
[1, 2, 3, 4, 1, 4, 6, 7]
重複したくない場合は、
>>> a = [1, 2, 3, 4, 5, 6]
>>> b = [5, 6, 7, 8]
>>> c = list(set(a + b))
>>> c
[1, 2, 3, 4, 5, 6, 7, 8]
list(set(listone) | set(listtwo))
上記のコードは、順序を保持せず、各リストから重複を削除します(ただし連結リストからは削除しません)。
list
オブジェクトに定義されたappend()
メソッドを使うことができます:
mergedlist =[]
for elem in listone:
mergedlist.append(elem)
for elem in listtwo:
mergedlist.append(elem)
すでに多くの人が指摘しているように、itertools.chain()
は、両方のリストに まったく同じ処理 を適用する必要がある場合に使用する方法です。私の場合、ラベルとフラグがリストごとに異なるため、少し複雑なものが必要でした。結局のところ、舞台裏でitertools.chain()
は単に次のようにします。
for it in iterables:
for element in it:
yield element
( https://docs.python.org/2/library/itertools.html を参照)ので、ここからインスピレーションを得て、以下の行に沿って何かを書きました。
for iterable, header, flag in ( (newList, 'New', ''), (modList, 'Modified', '-f')):
print header + ':'
for path in iterable:
[...]
command = 'cp -r' if os.path.isdir(srcPath) else 'cp'
print >> SCRIPT , command, flag, srcPath, mergedDirPath
[...]
ここで理解しておくべき主な点は、リストは他のオブジェクトと同じように反復可能な特殊なケースにすぎないということです。そして、pythonのfor ... in
ループはTuple変数を扱うことができるので、同時に複数の変数をループするのは簡単です。
Pythonで2つのリストを連結する方法
3.7以降、これらはpythonで2つ(以上)のリストを連結するための最も一般的なstdlibメソッドです。
脚注
これは簡潔さのために滑らかな解決策です。しかし
sum
はペアワイズ方式で連結を実行します。つまり、各ステップにメモリを割り当てる必要があるため、これは2次演算です。リストが大きい場合は使用しないでください。ドキュメントの
chain
とchain.from_iterable
を参照してください。あなたは最初にimport itertools
する必要があります。連結はメモリー内で線形であるため、これはパフォーマンスとバージョンの互換性の観点からは最適です。chain.from_iterable
は2.6で導入されました。この方法では 追加の展開一般化(PEP 448) を使いますが、手動で展開しない限りN個のリストに一般化することはできません。
a += b
とa.extend(b)
はすべての実用的な目的のために多かれ少なかれ同等です。リスト上で+=
を呼び出すと、内部でlist.__iadd__
が呼び出されます。これは、最初のリストを2番目のリストに拡張します。
2リスト連結 1
Nリスト連結
プロットは perfplot モジュールを使って生成されています。 コード、参考のために。
1. iadd
(+=
)メソッドとextend
メソッドはインプレースで動作するため、テストの前に毎回コピーを生成する必要があります。公平を期すために、すべての方法は左側のリストのためのコピー前のステップを持っていますが、無視することができます。
ダンサーメソッドlist.__add__
を直接、絶対に使用しないでください。実際には、dunderメソッドを避けて、演算子とoperator
関数を設計されたとおりに使用してください。 Pythonは慎重にそれらをまとめたセマンティクスを持っています。それはただ単にdunderを直接呼び出すよりももっと複雑です。これが の例です 。要約すると、a.__add__(b)
=> BADです。 a + b
=>良いです。
ここでのいくつかの答えは、ペアワイズ連結のためのreduce(operator.add, [a, b])
を提供します - これはsum([a, b], [])
と同じ意味ですが、これはもっと言葉遣いが多いです。
set
を使用するメソッドはすべて重複を削除し、順序を失います。慎重に使用してください。
for i in b: a.append(i)
は単発的な呼び出しでより慣用的なa.extend(b)
よりも語彙が多く、処理が遅くなります。 append
は、メモリが割り当てられてリストのために拡張されるという意味論のために遅くなります。同様の議論については ここ を参照してください。
heapq.merge
は動作しますが、そのユースケースはソートされたリストを線形時間でマージすることです。他の状況でそれを使用することはアンチパターンです。
関数からのyield
ingリスト要素は受け入れ可能な方法ですが、chain
はこれをより速く、より良くします(Cのコードパスを持っているので速い).
operator.add(a, b)
はa + b
と同等の許容できる機能です。そのユースケースは主に動的メソッドのディスパッチ用です。そうでなければ、短くて読みやすいa + b
、私の意見ではをお勧めします。 YMMV.
リストを別のリストに拡張するには、以下のようないくつかの方法があります。
>>> listone = [1,2,3]
>>> listome = [4,5,6]
>>>
>>> listone+listome # adding 2 list is actually extending the list
[1, 2, 3, 4, 5, 6]
>>>
>>> listone.extend(listome)
>>> listone
[1, 2, 3, 4, 5, 6]
>>>
>>> listone = [1,2,3]
>>>
>>> listone.__add__(listome)
[1, 2, 3, 4, 5, 6]
また、for loop
も使用できます。
>>> for i in listome:
... listone.append(i)
...
>>> listone
[1, 2, 3, 4, 5, 6]
>>>
Pythonでは、このコマンドで互換性のある次元の2つの配列を連結することができます
numpy.concatenate([a,b])
リストのリストを組み合わせるための本当に簡潔な方法は、
list_of_lists = [[1,2,3], [4,5,6], [7,8,9]]
reduce(list.__add__, list_of_lists)
それは私たちに与えます
[1, 2, 3, 4, 5, 6, 7, 8, 9]
lst1 = [1,2]
lst2 = [3,4]
def list_combinationer(Bushisms, are_funny):
for item in lst1:
lst2.append(item)
lst1n2 = sorted(lst2)
print lst1n2
list_combinationer(lst1, lst2)
[1,2,3,4]
単純なリスト内包表記を使う:
joined_list = [item for list_ in [list_one, list_two] for item in list_]
追加の展開一般化 - つまり、そのようにして任意の数の異なるイテラブル(たとえば、リスト、タプル、範囲、ジェネレータ)を連結することができます。 Python 3.5以降に制限されています。
Pythonでは2つのリストを連結するために '+'演算子を使うことができます。
>>> listone = [1,2,3]
>>> listtwo = [4,5,6]
>>>
>>> listSum = []
>>> listSum = listone + listtwo
>>> print(listSum)
[1, 2, 3, 4, 5, 6]
import itertools
A = list(Zip([1,3,5,7,9],[2,4,6,8,10]))
B = [1,3,5,7,9]+[2,4,6,8,10]
C = list(set([1,3,5,7,9] + [2,4,6,8,10]))
D = [1,3,5,7,9]
D.append([2,4,6,8,10])
E = [1,3,5,7,9]
E.extend([2,4,6,8,10])
F = []
for a in itertools.chain([1,3,5,7,9], [2,4,6,8,10]):
F.append(a)
print ("A: " + str(A))
print ("B: " + str(B))
print ("C: " + str(C))
print ("D: " + str(D))
print ("E: " + str(E))
print ("F: " + str(F))
出力:
A: [(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]
B: [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
C: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
D: [1, 3, 5, 7, 9, [2, 4, 6, 8, 10]]
E: [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
F: [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
2つの古いリストを残しながら新しいリストが欲しい場合は、
def concatenate_list(listOne, listTwo):
joinedList = []
for i in listOne:
joinedList.append(i)
for j in listTwo:
joinedList.append(j)
sorted(joinedList)
return joinedList
だから2つの簡単な方法があります。
+
を使う :提供されたリストから新しいリストを作成する例:
In [1]: a = [1, 2, 3]
In [2]: b = [4, 5, 6]
In [3]: a + b
Out[3]: [1, 2, 3, 4, 5, 6]
In [4]: %timeit a + b
10000000 loops, best of 3: 126 ns per loop
例:
In [1]: a = [1, 2, 3]
In [2]: b = [4, 5, 6]
In [3]: %timeit a.extend(b)
10000000 loops, best of 3: 91.1 ns per loop
したがって、2つの最も一般的な方法のうち、extend
が効率的です。