Pythonで2つのリストを連結するにはどうすればよいですか?
例:
listone = [1, 2, 3]
listtwo = [4, 5, 6]
期待される結果:
>>> joinedlist
[1, 2, 3, 4, 5, 6]
[1,2,5] and [2,4,5,6]
か?重複を含めたり、除外したり、無視したりしますか?
Pythonで2つのリストを連結するにはどうすればよいですか?
例:
listone = [1, 2, 3]
listtwo = [4, 5, 6]
期待される結果:
>>> joinedlist
[1, 2, 3, 4, 5, 6]
[1,2,5] and [2,4,5,6]
か?重複を含めたり、除外したり、無視したりしますか?
回答:
+
演算子を使用してそれらを組み合わせることができます。
listone = [1,2,3]
listtwo = [4,5,6]
joinedlist = listone + listtwo
出力:
>>> joinedlist
[1,2,3,4,5,6]
listone += listtwo
で結果listone == [1, 2, 3, 4, 5, 6]
list3 = listone
listone+=listtwo
list3も変更されますか?
を使用して、両方のリストの項目を単純に反復するジェネレータを作成することもできますitertools.chain()
。これにより、アイテムを新しいリストにコピーせずに、リスト(または任意の反復可能)をチェーンして処理することができます。
import itertools
for item in itertools.chain(listone, listtwo):
# Do something with each list item
chain
2つのリストの場合は(それほど多くはありませんが)遅い側にありますが、複数のリストを連鎖させる(n >> 2)ための最も速いソリューションです。
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
コンテンツから単純にを作成するためです。
res = [*l1, *reversed(l2)]
。以来reversed
返すイテレータ、res = l1 + reversed(l2)
エラーをスローします。
セットを使用して、一意の値のマージされたリストを取得できます
mergedlist = list(set(listone + listtwo))
listone + [x for x in listtwo if x not in listone]
import collections; mergedlist = list(collections.OrderedDict.fromkeys(listone + listtwo))
は、トリックを実行します。
list.extend()
メソッドを使用してlist
、別の1つの末尾にを追加することもできます。
listone = [1,2,3]
listtwo = [4,5,6]
listone.extend(listtwo)
元のリストをそのまま維持したい場合は、新しいlist
オブジェクトを作成し、extend
両方のリストにそのオブジェクトを追加できます。
mergedlist = []
mergedlist.extend(listone)
mergedlist.extend(listtwo)
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
メソッドはインプレースで動作するため、テストの前に毎回コピーを生成する必要があります。公平を期すために、すべてのメソッドには、左側のリストのコピー前のステップがありますが、これは無視できます。
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。
"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ない『私は使用しないことをお勧めコメント』。
これは非常に単純で、チュートリアルにも示されていると思います。
>>> 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, [])
reduce
が入っているfunctools
ので、最初にインポートする必要があります。
この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']
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
独自の関数を定義する代わりに、(同等の)を使用できます。
2つのリストをソートされた形式でマージする場合merge
は、heapq
ライブラリの関数を使用できます。
from heapq import merge
a = [1, 2, 4]
b = [2, 4, 6, 7]
print list(merge(a, b))
プラス演算子(+
)を使用できない場合は、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]
+
がテーブルから外れている場合は、を使用しますoperator.add
。
より多くのリストのより一般的な方法として、リスト内にそれらを配置し、この回答に基づいてネストされたリストをフラット化するための最良の方法である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)
。
複雑な並べ替えルールで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
。
オブジェクトでappend()
定義されたメソッドを使用できlist
ます:
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
[...]
ここで理解しておくべき重要な点は、リストは反復可能な特殊なケースにすぎず、他のオブジェクトと同様です。またfor ... in
、Pythonのループはタプル変数を処理できるため、複数の変数を同時にループするのは簡単です。
リストのリストを組み合わせる本当に簡潔な方法は
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, [])
同じくらい悪いものです。使ってはいけません!
obj.__class__
およびobj.__dict__
です。
したがって、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
効率的であることがわかります。
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
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]