2012-07-03 7 views

Trả lời

31

gì bạn tìm kiếm là itertools.izip_longest

>>> a = [1,2,3] 
>>> b = [9,10] 
>>> for i in itertools.izip_longest(a,b): print i 
... 
(1, 9) 
(2, 10) 
(3, None) 

EDIT 1: Nếu bạn thực sự muốn thoát khỏi None s, sau đó bạn có thể thử:

>>> for i in (filter(None, pair) for pair in itertools.izip_longest(a,b)): print i 
(1, 9) 
(2, 10) 
(3,) 

EDIT 2: Để trả lời bình luận của steveha:

filter(lambda p: p is not None, pair) for pair in itertools.izip_longest(a,b) 
+7

Sử dụng 'itertools.zip_longest' cho Python 3.5+. –

7

Một cách khác là map:

a = [1, 2, 3] 
b = [9, 10] 
c = map(None, a, b) 

Mặc dù điều đó quá sẽ chứa (3, None) thay vì (3,). Để làm điều đó, đây là một đường vui vẻ:

c = (tuple(y for y in x if y is not None) for x in map(None, a, b)) 
+0

'x nếu Không có trong x khác tuple (y cho y trong x nếu y không phải là None)'. 'X if None not in x' là thừa ở đây, vì' else' sẽ xử lý nó. Trong trường hợp xấu nhất, 'else' sẽ trả về một tuple rỗng. Ngoài ra, nếu có 'None' trong bất kỳ tuple nào,' if' sẽ giết tuple đó và chuyển nó vào 'else' – inspectorG4dget

+0

@ inspectorG4dget: Cảm ơn.Nhưng bây giờ nó không phải là khá thú vị: D – Ryan

+0

Hoạt động độc đáo trong Python 2.7, nhưng không phải trong 3.5. Đối với 3.5, sử dụng 'itertools.zip_longest'. –

2

Nó không phải quá khó để chỉ viết Python rõ ràng để làm các hoạt động mong muốn:

def izip_short(a, b): 
    ia = iter(a) 
    ib = iter(b) 
    for x in ia: 
     try: 
      y = next(ib) 
      yield (x, y) 
     except StopIteration: 
      yield (x,) 
      break 
    for x in ia: 
     yield (x,) 
    for y in ib: 
     yield (None, y) 

a = [1, 2, 3] 
b = [9, 10] 
list(izip_short(a, b)) 
list(izip_short(b, a)) 

Tôi đã không chắc chắn làm thế nào bạn sẽ muốn để xử lý trình tự b dài hơn trình tự a, vì vậy, tôi chỉ cần nhập số None cho giá trị đầu tiên trong bộ tuple trong trường hợp đó.

Nhận trình lặp lặp lại rõ ràng cho mỗi chuỗi. Chạy trình chuyển đổi a dưới dạng vòng lặp for, trong khi sử dụng thủ công next(ib) để nhận giá trị tiếp theo từ trình tự b. Nếu chúng tôi nhận được một StopIteration trên trình tự b, chúng tôi sẽ ngắt vòng lặp và sau đó for x in ia: sẽ nhận được phần còn lại của chuỗi a; sau đó for y in ib: sẽ không làm gì vì trình lặp đó đã hết. Ngoài ra, nếu vòng lặp for x in ia: đầu tiên loại bỏ thiết bị lặp a, thì for x in ia: thứ hai không làm gì ngoài các giá trị còn lại trong trình tự b và vòng lặp for y in ib: thu thập chúng.

1

dòng đơn:

c = zip(a, b) + [(x,) for x in a[len(b):]] + [(x,) for x in b[len(a):]]

Nếu bạn muốn sử dụng này:

def mergeUsNicely(a, b): 
    def tupleMe(val): 
     return (val,) 
    return zip(a, b) + map(tupleMe, a[len(b):]) + map(tupleMe, b[len(a):])