Pythonで2つのリストを連結するにはどうすればよいですか?


2531

Pythonで2つのリストを連結するにはどうすればよいですか?

例:

listone = [1, 2, 3]
listtwo = [4, 5, 6]

期待される結果:

>>> joinedlist
[1, 2, 3, 4, 5, 6]

6
単純に追加しますか、それとも2つのリストをソート順マージしますか?[1,3,6]と[2,4,5]にはどのような出力が期待できますか?両方のサブリストがすでにソートされていると想定できますか(例のように)?
smci

1
...リストに重複がある場合はどうなります[1,2,5] and [2,4,5,6]か?重複を含めたり、除外したり、無視したりしますか?
smci

回答:


3905

+演算子を使用してそれらを組み合わせることができます。

listone = [1,2,3]
listtwo = [4,5,6]

joinedlist = listone + listtwo

出力:

>>> joinedlist
[1,2,3,4,5,6]

110
これはlistoneの深いコピーを作成し、listtwoを追加しますか?
ダニエルF

152
@Danielは、最初のリストの項目の浅いコピーを含む新しいリストを作成し、次に2番目のリストの項目の浅いコピーを作成します。リストの詳細なコピーを取得するには、copy.deepcopyを使用します。
Daniel G

219
ここでは、別の有用な詳細:listone += listtwoで結果listone == [1, 2, 3, 4, 5, 6]
rickcnagy

16
@ br1ckb0tこれは、listoneが指しているものを変更しますか?だから:list3 = listone listone+=listtwo list3も変更されますか?
MikeH 2014

11
list3を変更します。ただし、それが問題でない場合は、新しいリストを作成する代わりに、2つのリストを追加する方が読みやすくなります。
rickcnagy 14

319

を使用して、両方のリストの項目を単純に反復するジェネレータを作成することもできますitertools.chain()。これにより、アイテムを新しいリストにコピーせずに、リスト(または任意の反復可能)をチェーンして処理することができます。

import itertools
for item in itertools.chain(listone, listtwo):
    # Do something with each list item

4
chain2つのリストの場合は(それほど多くはありませんが)遅い側にありますが、複数のリストを連鎖させる(n >> 2)ための最も速いソリューションです。
cs95

@ cs95は何に比べて遅いですか?
Moberg

@Mobergリストを連結する他の方法と比較して、参考として、こちらのベンチマークを参照してください。
cs95

265

Pythonの>= 3.5代替:[*l1, *l2]

PEP 448言及するに値するものの受け入れを通じて、別の代替案が導入されました。

追加のアンパックの一般化」というタイトルのPEPは、*Pythonでスター付きの式を使用するときの一般的な構文上の制限を減らしました。これにより、2つのリストの結合(イテラブルすべてに適用)も次のように実行できます。

>>> l1 = [1, 2, 3]
>>> l2 = [4, 5, 6]
>>> joined_list = [*l1, *l2]  # unpack both iterables in a list literal
>>> print(joined_list)
[1, 2, 3, 4, 5, 6]

この機能はPython用に定義されたもの3.5で、3.xファミリーの以前のバージョンにバックポートされていません。サポートされていないバージョンでSyntaxErrorはa が発生します。

他のアプローチと同様に、これも対応するリストの要素の浅いコピーとして作成されます。


逆さまこのアプローチには、あなたが本当に、それを実行するために、反復可能で行いますで何かをリストを必要としないことです。PEPで述べられているように:

これは、次のような、また、リストに反復可能オブジェクトを合計するより読みやすい方法として有用であるmy_list + list(my_tuple) + list(my_range)今ちょうどに相当します[*my_list, *my_tuple, *my_range]

したがって、withを追加する+TypeError型の不一致が原因で発生しますが、

l = [1, 2, 3]
r = range(4, 7)
res = l + r

次のことはできません:

res = [*l, *r]

これは、最初にイテラブルのコンテンツを解凍し、次にlistコンテンツから単純にを作成するためです。


1
反復可能な型に取り組んでいるアンパックアプローチの良い例は、連結しているリストの1つに対して反復子を返す関数です。たとえば、連結しているリストの1つを逆にすることができますres = [*l1, *reversed(l2)]。以来reversed返すイテレータ、res = l1 + reversed(l2)エラーをスローします。
アラン

2
これは、Pythonで辞書を組み合わせるのに似ていることに注意してください。dict3 = {** dict1、** dict2}。**を使用してディクショナリをアンパックするのに対し、リストでは*を使用してアンパックします。
Kevin S

213

セットを使用して、一意の値のマージされたリストを取得できます

mergedlist = list(set(listone + listtwo))

45
確かに、しかし、それがあなたが興味を持っているものであるなら、それは重複も取り除きます。リストの追加はそれを行いません。
メタソアロウ

1
それを行い、注文情報を保持する方法は何ですか?
Natim 2013年

11
より良いlistone + [x for x in listtwo if x not in listone]
Natim 2013年

8
+1 IMHOこれはリストを「マージ」(結合)するための正しい方法ですが、「承認済み」の回答はリストを結合/追加する方法(マルチセット)を説明します
alfasin

2
入力順序を維持する必要がある場合import collections; mergedlist = list(collections.OrderedDict.fromkeys(listone + listtwo))は、トリックを実行します。
SethMMorton 2016

186

list.extend()メソッドを使用してlist、別の1つの末尾にを追加することもできます。

listone = [1,2,3]
listtwo = [4,5,6]

listone.extend(listtwo)

元のリストをそのまま維持したい場合は、新しいlistオブジェクトを作成し、extend両方のリストにそのオブジェクトを追加できます。

mergedlist = []
mergedlist.extend(listone)
mergedlist.extend(listtwo)

81

Pythonで2つのリストを連結するにはどうすればよいですか?

3.7以降、これらはPythonで2つ(またはそれ以上)のリストを連結するための最も一般的なstdlibメソッドです。

ここに画像の説明を入力してください

脚注

  1. 簡潔さのため、これは洗練されたソリューションです。しかしsum、ペアワイズ方式で連結を実行します。これは、各ステップにメモリを割り当てる必要があるため、これは2次演算であることを意味します。リストが大きい場合は使用しないでください。

  2. 参照chain および chain.from_iterable ドキュメントから。import itertools最初にする必要があります。連結はメモリ内で線形であるため、パフォーマンスとバージョンの互換性の点でこれが最適です。chain.from_iterable2.6で導入されました。

  3. この方法では、追加のアンパックの一般化(PEP 448)を使用しますが、手動でそれぞれをアンパックしない限り、Nリストに一般化することはできません。

  4. a += bそしてa.extend(b)、すべての実用的な目的のために多かれ少なかれ同等です。+=リストで呼び出されると、内部的にを呼び出し list.__iadd__、最初のリストを2番目に拡張します。


パフォーマンス

2リスト連結1

ここに画像の説明を入力してください

これらの方法には大きな違いはありませんが、すべて同じ程度の複雑さ(線形)であることを考えると、それは理にかなっています。スタイルの問題を除いて、どちらか一方を優先する特別な理由はありません。

Nリスト連結

ここに画像の説明を入力してください

プロットは、perfplotモジュールを使用して生成されています。参考までに、コード。

1. iadd+=)とextendメソッドはインプレースで動作するため、テストの前に毎回コピーを生成する必要があります。公平を期すために、すべてのメソッドには、左側のリストのコピー前のステップがありますが、これは無視できます。


他のソリューションに関するコメント

  • DUNDERメソッドlist.__add__を形、形を問わず直接使用しないでください。実際、ダンダーメソッドに近づかないで、演算子と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関数からリスト要素を使用することは許容できる方法ですが、これchainはより速く、よりよくできます(Cにはコードパスがあるため、高速です)。

  • operator.add(a, b)は、と同等の許容可能な機能ですa + b。ユースケースは主に動的メソッドのディスパッチです。そうでなければ、私の意見a + bでは、どちらがより短く、より読みやすいかを好みます。YMMV。


回答stackoverflow.com/q/36863404/125507は(numba液を含む)perfplotプロットを使用することができます
endolith

@endolithは少し仕事で溢れていますが、私は調べてチップインできるかどうかを確認します。
cs95

パフォーマンスの点で最も速い方法はどれですか?教えてください。
ganeshdeshmukh

@ganeshdeshmukh TL; DRはどれも優れていて、どれを選ぶかはスタイルの問題です。"There's not much difference between these methods but that makes sense given they all have the same order of complexity (linear). There's no particular reason to prefer one over the other except as a matter of style."ソリューションは、私の答えに記載されている、またはにcritizedない『私は使用しないことをお勧めコメント』。
cs95


51

この質問は、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, [])

3
Python 3注:reduceが入っているfunctoolsので、最初にインポートする必要があります。
Dimitris Fasarakis Hilliard 2017

41

次のように単純に+or +=演算子を使用できます。

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

最後の部分では、アイテムを任意に並べ替えることができます。順序を維持したい場合は、CPython 3.6以降で実行できますlist(dict.fromkeys(a + b))
Boris

27

この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']

イテラブル(タプル、リスト、ジェネレーターなど)が入力の場合、from_iterableクラスメソッドを使用できます。

>>> il = [['a'], ['b', 'c'], ['d', 'e', 'f']]
>>> [i for i in itertools.chain.from_iterable(il)]
['a', 'b', 'c', 'd', 'e', 'f']

22

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]

itertools.chain独自の関数を定義する代わりに、(同等の)を使用できます。
ボリス

18

2つのリストをソートされた形式でマージする場合mergeは、heapqライブラリの関数を使用できます。

from heapq import merge

a = [1, 2, 4]
b = [2, 4, 6, 7]

print list(merge(a, b))

15

プラス演算子(+)を使用できない場合は、operatorインポートを使用できます。

import operator

listone = [1,2,3]
listtwo = [4,5,6]

result = operator.add(listone, listtwo)
print(result)

>>> [1, 2, 3, 4, 5, 6]

または、__add__ dunder関数を使用することもできます。

listone = [1,2,3]
listtwo = [4,5,6]

result = list.__add__(listone, listtwo)
print(result)

>>> [1, 2, 3, 4, 5, 6]

3
ダンダーをつかむことは、一般的に最良のアプローチではありません。+がテーブルから外れている場合は、を使用しますoperator.add
Dimitris Fasarakis Hilliard 2017

2
plus演算子が使用できないのはなぜですか?
cs01

2
通常は:)ではありませんが、map関数でリスト連結を行っている場合、またはadd関数を変数に格納したい場合は、+を使用できません。
jpihl

13

より多くのリストのより一般的な方法として、リスト内にそれらを配置し、この回答に基づいてネストされたリストをフラット化するための最良の方法であるitertools.chain.from_iterable()1関数を使用できます。

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


10

複雑な並べ替えルールで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])

または単に使用しますheapq.merge
cs95

7

オブジェクトでappend()定義されたメソッドを使用できlistます:

mergedlist =[]
for elem in listone:
    mergedlist.append(elem)
for elem in listtwo:
    mergedlist.append(elem)

9
これが実際にやっているのであれば、これは他の提案された方法よりもはるかに遅くなります。stackoverflow.com/questions/17479361/…を
Ryan Haining

7
list(set(listone) | set(listtwo))

上記のコードは、順序を保持せず、各リストから重複を削除します(ただし、連結リストからは削除しません)


6

すでに多くの人が指摘して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
        [...]

ここで理解しておくべき重要な点は、リストは反復可能な特殊なケースにすぎず、他のオブジェクトと同様です。またfor ... in、Pythonのループはタプル変数を処理できるため、複数の変数を同時にループするのは簡単です。


5

単純なリスト内包表記を使用します。

joined_list = [item for list_ in [list_one, list_two] for item in list_]

追加のアンパッキング汎化を使用する最新のアプローチのすべての利点があります。つまり、任意の数の異なる反復可能オブジェクト(たとえば、リスト、タプル、範囲、およびジェネレーター)をそのように連結できます。これは、Python 3.5以降に限定されません。 。


4

リストのリストを組み合わせる本当に簡潔な方法は

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]

使用せずlist.__add__operator.add代わりに使用してください。これは、より言葉に相当するもので、sum(list_of_lists, [])同じくらい悪いものです。使ってはいけません!
cs95

@ cs95では、list .__ add__を使用して問題の説明をしていただけますか
Akash Singh

dunderメソッドは「プライベートメソッド」であり、通常は直接使用しないでください(他の関数から呼び出されます)。例外はobj.__class__およびobj.__dict__です。
cs95


2

したがって、2つの簡単な方法があります。

  1. 使用+:提供されたリストから新しいリストを作成します

例:

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
  1. 拡張の使用:既存のリストに新しいリストを追加します。つまり、個別のリストは作成されません。

例:

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効率的であることがわかります。


2
a + b + c + d + eのように複数のリストを追加する必要がある場合はどうなりますか?
Tweakimp

2
@Tweakimp いくつかのオプションがある(このことをお勧めします)この回答を参照してくださいchain.from_iterable
cs95

2

Pythonでリストを連結する方法は複数あります。

l1 = [1,2,3,4]
l2 = [3,4,5,6]

 1. new_list = l1.copy()
    new_list = new_list.extend(l2)
 2. new_list = l1 + l2
 3. new_list = [*l1, *l2]

1
この回答が他にどのような新しい情報を提供するか説明していただけませんか?
cs95

Pythonでリストを連結する方法は複数あります。これらはすべて、他のはるかに古い回答で広くカバーされています。これはどのような新しい情報を提供しますか?
Tomerikoo

-1
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]

-1

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

それはmingxiaoによるこの回答とどう違うのですか?
Tomerikoo

-2
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]

4
さて、説明をお願いします
U10-Forward

関数内でグローバル名を使用している場合、関数の引数の意味は何ですか?
Tomerikoo

-2

あなたはコードに従うことができます

listone = [1, 2, 3]
listtwo = [4, 5, 6]

for i in listone:
    listtwo.append(i)
print(listtwo)

[1,2,3,4,5,6]
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.