วิธีการรวมรายการลงในรายการสิ่งอันดับ?


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เป็น tuple ซึ่งสมาชิกคนแรกจากและสองคือจากlist_alist_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
คุณต้องรู้ว่าฟังก์ชั่นซิปหยุดที่ส่วนท้ายของรายการที่สั้นที่สุดซึ่งอาจไม่ใช่สิ่งที่คุณต้องการ itertoolsโมดูลกำหนดzip_longest()วิธีการที่จะหยุดในตอนท้ายของรายการที่ยาวที่สุดเติมค่าที่ขาดหายไปกับสิ่งที่คุณให้เป็นพารามิเตอร์
Adrien Plisson

5
@Adrien: ขอบคุณสำหรับความคิดเห็นของคุณ สำหรับงูหลาม s/zip_longest()/izip_longest()2.x, เปลี่ยนชื่อในหลาม 3.x zip_longest()ไป
mechanical_meat

ฉันสามารถสร้าง [(1,5), (1,6), (1,7), (1,8), (2,5), (2,6), ต่อไป] โดยใช้คำสั่ง zip หรือไม่
Mona Jalal

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 for loop จะให้ตัวสร้างที่จะเหนื่อยหลังจากใช้เพียงครั้งเดียว บันทึกเป็นตัวแปรหากคุณต้องการใช้มันบ่อยขึ้น
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

ฉันมีสิทธิ์เข้าถึง python 3.5 เท่านั้น
Dark Knight

3
ถ้าคุณใช้ python3 แล้ว c จะไม่ใช่ลิสต์มันจะเป็นวัตถุแผนที่การใช้แลมบ์ดาจะมีประสิทธิภาพน้อยกว่าการซิปซิมถ้าคุณมีรายการความยาวต่างกันและต้องการจัดการกับมันคุณก็จะใช้ izip_longest / zip_longest
Padraic Cunningham


6

ฉันไม่แน่ใจว่านี่เป็นวิธี pythonic หรือไม่ แต่ดูเหมือนง่ายถ้าทั้งสองรายการมีจำนวนองค์ประกอบเท่ากัน:

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
การเปลี่ยนหนึ่งในรายการอินพุต (หากมีความยาวต่างกัน) จะไม่มีผลข้างเคียงที่ดี นอกจากนี้ทั้งสองได้รับมอบหมายไปcardในที่ไม่จำเป็นที่ว่าทำไมคุณมีif-elif continue(ในความเป็นจริงโดยไม่ต้องcontinueคุณจะไม่ต้องมีการเปลี่ยนแปลงรายการทั้งที่ได้รับมอบหมายกล่าวก่อนหน้านี้แล้วควรจะเก็บไว้และเป็นcard = (list_1[i], '')และcard = ('', list_2[1])ตามลำดับ.)
ᴠɪɴᴄᴇɴᴛ

5

เอาท์พุทที่คุณแสดงให้เห็นในคำสั่งปัญหาไม่ได้เป็นสิ่งอันดับ แต่รายการ

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

ตรวจสอบ

type(list_c)

เมื่อพิจารณาว่าคุณต้องการผลลัพธ์เป็น tuple จาก list_a และ list_b ให้ทำ

tuple(zip(list_a,list_b)) 

จากมุมมองของฉันดูเหมือนว่าเป็นสิ่งที่ฉันกำลังมองหาและทำงานได้ดีสำหรับทั้ง (รายการและทูเปิล) เพราะเมื่อคุณใช้การพิมพ์คุณจะเห็นคุณค่าทางขวา (ตามที่คาดไว้และ mentionned โดย @cyborg และ @Lodewijk) และไม่มีอะไรที่เกี่ยวข้องกับวัตถุเช่น: หรือ<map object at 0x000001F266DCE5C0> <zip object at 0x000002629D204C88>อย่างน้อยโซลูชันเกี่ยวกับแผนที่และรหัสไปรษณีย์ (เพียงอย่างเดียว) ดูเหมือนว่าจะไม่สมบูรณ์ (หรือซับซ้อนเกินไป) สำหรับฉัน
Wagner_SOFC

1
คำถามระบุว่าพวกเขาต้องการรายชื่อของสิ่งอันดับไม่ใช่สิ่งอันดับของสิ่งอันดับ
goryh

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.