มีฟังก์ชั่นคล้ายซิปที่มีความยาวสูงสุดใน Python หรือไม่?


170

มีฟังก์ชั่นในตัวที่ทำงานเหมือนzip()แต่จะเสริมผลลัพธ์เพื่อให้ความยาวของรายการผลลัพธ์เป็นความยาวของอินพุตที่ยาวที่สุดแทนที่จะเป็นอินพุตที่สั้นที่สุด ?

>>> a = ['a1']
>>> b = ['b1', 'b2', 'b3']
>>> c = ['c1', 'c2']

>>> zip(a, b, c)
[('a1', 'b1', 'c1')]

>>> What command goes here?
[('a1', 'b1', 'c1'), (None, 'b2', 'c2'), (None, 'b3', None)]

คำตอบ:


243

ใน Python 3 คุณสามารถใช้ itertools.zip_longest

>>> list(itertools.zip_longest(a, b, c))
[('a1', 'b1', 'c1'), (None, 'b2', 'c2'), (None, 'b3', None)]

คุณสามารถผัดด้วยค่าที่แตกต่างNoneจากการใช้fillvalueพารามิเตอร์:

>>> list(itertools.zip_longest(a, b, c, fillvalue='foo'))
[('a1', 'b1', 'c1'), ('foo', 'b2', 'c2'), ('foo', 'b3', 'foo')]

กับงูหลาม 2 คุณสามารถใช้itertools.izip_longest(Python 2.6+) หรือคุณสามารถใช้กับmap Noneมันเป็นคุณสมบัติที่mapรู้จักกันเล็กน้อยของ (แต่mapเปลี่ยนแปลงใน Python 3.x ดังนั้นจึงใช้งานได้ใน Python 2.x เท่านั้น)

>>> map(None, a, b, c)
[('a1', 'b1', 'c1'), (None, 'b2', 'c2'), (None, 'b3', None)]

3
เราไม่มีโซลูชัน Python 3 ที่ไม่ใช่ itertools หรือไม่
PascalVKooten

3
@PascalvKooten ไม่จำเป็นต้องใช้ itertoolsเป็นโมดูล C ในตัวต่อไป
Antti Haapala

82

สำหรับงูหลาม 2.6 เท่าการใช้งานโมดูลitertoolsizip_longest

สำหรับ Python 3 ให้ใช้zip_longestแทน (ไม่มีส่วนนำi)

>>> list(itertools.izip_longest(a, b, c))
[('a1', 'b1', 'c1'), (None, 'b2', 'c2'), (None, 'b3', None)]

8
ในกรณีที่คุณต้องการให้โค้ดของคุณรองรับทั้ง python 2 และ python 3 คุณสามารถใช้six.moves.zip_longestแทนได้
Gamrix

5

วิธีแก้ปัญหา non itertools Python 3:

def zip_longest(*lists):
    def g(l):
        for item in l:
            yield item
        while True:
            yield None
    gens = [g(l) for l in lists]    
    for _ in range(max(map(len, lists))):
        yield tuple(next(g) for g in gens)

2

ไม่ใช่ itertools โซลูชัน My Python 2:

if len(list1) < len(list2):
    list1.extend([None] * (len(list2) - len(list1)))
else:
    list2.extend([None] * (len(list1) - len(list2)))

0

ฉันใช้อาร์เรย์ 2 มิติ แต่แนวคิดคล้ายกับการใช้ python 2.x:

if len(set([len(p) for p in printer])) > 1:
    printer = [column+['']*(max([len(p) for p in printer])-len(column)) for column in printer]

2
โปรดเพิ่มคำอธิบายว่าทำไมรหัสนี้จึงใช้งานได้ หรือทำไมมันถึงเป็นคำตอบที่ถูกต้อง
Suit Boy Apps
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.