リストをタプルのリストにマージする方法は?


298

次を達成するためのPythonicのアプローチは何ですか?

# Original lists:

list_a = [1, 2, 3, 4]
list_b = [5, 6, 7, 8]

# List of tuples from 'list_a' and 'list_b':

list_c = [(1,5), (2,6), (3,7), (4,8)]

の各メンバーlist_cはタプルです。最初のメンバーはfrom list_aで、2番目のメンバーはfrom list_bです。

回答:


443

Python 2の場合:

>>> list_a = [1, 2, 3, 4]
>>> list_b = [5, 6, 7, 8]
>>> zip(list_a, list_b)
[(1, 5), (2, 6), (3, 7), (4, 8)]

Python 3の場合:

>>> list_a = [1, 2, 3, 4]
>>> list_b = [5, 6, 7, 8]
>>> list(zip(list_a, list_b))
[(1, 5), (2, 6), (3, 7), (4, 8)]

77
zip関数は最短リストの最後で停止することを知っておく必要がありますが、これは必ずしも希望するものとは限りません。このitertoolsモジュールはzip_longest()、最長のリストの最後で停止するメソッドを定義し、パラメーターとして指定したもので欠損値を埋めます。
Adrien Plisson、2010年

5
@Adrien:該当するコメントを歓迎します。Python 2.xの場合、s/zip_longest()/izip_longest()。Python 3.xでに名前が変更されましたzip_longest()
Mechanical_Meat

zipコマンドを使用して[(1,5)、(1,6)、(1,7)、(1,8)、(2,5)、(2,6)など)を作成できますか?
Mona Jalal 2016年

3
@MonaJalal:いいえ、それはペアになっていない、それはリストの製品を作成しています。itertools.product()それを行います。
Martijn Pieters

2
少なくともpython3.6では、zipはリストを返しません。したがって、代わりにlist(zip(list_a、list_b))が必要です
Supamee

141

Python 3.0では、zipはzipオブジェクトを返します。を呼び出すことで、リストを取得できますlist(zip(a, b))


3
これは些細なことかもしれませんが、これをforループで直接使用すると、一度使用すると使い果たされるジェネレータが提供されることに注意してください。頻繁に使用する場合は変数に保存してください
Hakaishin

13

マップラムダを使用できます

a = [2,3,4]
b = [5,6,7]
c = map(lambda x,y:(x,y),a,b)

これは、元のリストの長さが一致しない場合にも機能します


1
なぜラムダを使うのですか?map(None, a,b)
Padraic Cunningham 2016

私はpython 3.5にしかアクセスできません。
ダークナイト

3
python3を使用している場合、cはリストではなく、マップオブジェクトになります。また、異なる長さのリストがあり、それを処理したい場合、ラムダを使用すると、zipを実行するよりも効率が大幅に低下します。 izip_longest / zip_longest
Padraic Cunningham


6

これがPython的な方法であるかどうかはわかりませんが、両方のリストに同じ数の要素がある場合、これは単純なようです:

list_a = [1, 2, 3, 4]

list_b = [5, 6, 7, 8]

list_c=[(list_a[i],list_b[i]) for i in range(0,len(list_a))]

5

これは古い質問であり、すでに回答済みであることがわかっていますが、何らかの理由で、この代替ソリューションを投稿したいと思います。どの組み込み関数が必要な「マジック」を実行するかを見つけるのは簡単ですが、自分で実行できることを知っていても問題はありません。

>>> list_1 = ['Ace', 'King']
>>> list_2 = ['Spades', 'Clubs', 'Diamonds']
>>> deck = []
>>> for i in range(max((len(list_1),len(list_2)))):
        while True:
            try:
                card = (list_1[i],list_2[i])
            except IndexError:
                if len(list_1)>len(list_2):
                    list_2.append('')
                    card = (list_1[i],list_2[i])
                elif len(list_1)<len(list_2):
                    list_1.append('')
                    card = (list_1[i], list_2[i])
                continue
            deck.append(card)
            break
>>>
>>> #and the result should be:
>>> print deck
>>> [('Ace', 'Spades'), ('King', 'Clubs'), ('', 'Diamonds')]

2
入力リストの1つを変更すると(長さが異なる場合)、良い副次効果はありません。また、には2つの割り当てcardでは、if-elifあなたが持っている理由だと、必要とされていませんcontinue。(実際、continueあなたがいなければ、リストを変更する必要はありません。前述の両方の割り当てを保持しcard = (list_1[i], '')card = ('', list_2[1])それぞれにする必要があります。)
ᴠɪɴᴄᴇɴᴛJan

5

問題文で示した出力はタプルではなくリストです

list_c = [(1,5), (2,6), (3,7), (4,8)]

チェックする

type(list_c)

list_aとlist_bからタプルとして結果を取得したい場合は、次のようにします。

tuple(zip(list_a,list_b)) 

私の観点からは、それが私が探しているものであり、両方(リストとタプル)でうまく機能するようです。なぜなら、printを使用すると、正しい値(@cyborgと@Lodewijkによって予想され、言及されている)と、:や。などのオブジェクトに関連するものは何も表示されないからです。少なくとも、mapzip(単独)に関するソリューションは、私には不完全(または複雑すぎる)のようです。<map object at 0x000001F266DCE5C0><zip object at 0x000002629D204C88>
Wagner_SOFC 2017年

1
質問では、タプルのタプルではなく、タプルのリストが必要であると述べています。
goryh

1

を使用しない1つの代替zip

list_c = [(p1, p2) for idx1, p1 in enumerate(list_a) for idx2, p2 in enumerate(list_b) if idx1==idx2]

1番目と1番目、2番目と2番目のタプルだけでなく、2つのリストのすべての可能な組み合わせを取得したい場合は、

list_d = [(p1, p2) for p1 in list_a for p2 in list_b]
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.