2010-07-09 30 views
99

Tôi muốn thay đổi đoạn mã sauLàm thế nào để tham gia hai máy phát điện bằng Python?

for directory, dirs, files in os.walk(directory_1): 
    do_something() 

for directory, dirs, files in os.walk(directory_2): 
    do_something() 

để mã này:

for directory, dirs, files in os.walk(directory_1) + os.walk(directory_2): 
    do_something() 

tôi nhận được lỗi:

unsupported operand type(s) for +: 'generator' and 'generator'

Làm thế nào để tham gia hai máy phát điện bằng Python?

+1

tôi cũng như Python để làm việc theo cách này. Có chính xác cùng một lỗi! –

Trả lời

141

Tôi nghĩ rằng itertools.chain() nên làm điều đó.

+1

http://docs.python.org/library/itertools.html – reto

+3

yep, đây chính xác là những gì 'chain()' là dành cho –

+16

Khi sử dụng 'itertools.chain' để nối hai không thể lặp lại, như trong câu hỏi, nhưng tất cả các iterables trong một iterable (ví dụ, 'chain (* imap (xrange, xrange (5)))'), bạn có thể chạy vào [Python bug # 4806] (http://bugs.python.org/issue4806), mặt nạ bất kỳ TypeError lớn lên trong vòng lặp và dẫn đến một thông báo lỗi khó hiểu. Ngoài ra, bạn có thể sử dụng 'itertools.chain.from_iterable' (kể từ Python 2.6) trong trường hợp đó, trực tiếp lấy iterable của iterables làm đối số:' chain.from_iterable (imap (xrange, xrange (5))) '. –

29

Một ví dụ về mã:

from itertools import chain 

def generator1(): 
    for item in 'abcdef': 
     yield item 

def generator2(): 
    for item in '123456': 
     yield item 

generator3 = chain(generator1(), generator2()) 
for item in generator3: 
    print item 
5

Với itertools.chain.from_iterable bạn có thể làm những việc như:

def genny(start): 
    for x in range(start, start+3): 
    yield x 

y = [1, 2] 
ab = [o for o in itertools.chain.from_iterable(genny(x) for x in y)] 
print(ab) 
1

ví dụ đơn giản:

from itertools import chain 
x = iter([1,2,3])  #Create Generator Object (listiterator) 
y = iter([3,4,5])  #another one 
result = chain(x, y) #Chained x and y 
0

Nếu bạn muốn giữ các máy phát riêng biệt nhưng vẫn lặp lại chúng cùng một lúc, bạn có thể sử dụng zip():

LƯU Ý: Iteration dừng lại ở ngắn của hai máy phát điện

Ví dụ:

for (root1, dir1, files1), (root2, dir2, files2) in zip(os.walk(path1), os.walk(path2)): 

    for file in files1: 
     #do something with first list of files 

    for file in files2: 
     #do something with second list of files 
0

phép nói rằng chúng ta phải phát điện (gen1 và gen 2) và chúng tôi muốn thực hiện thêm một số tính toán rằng yêu cầu kết quả của cả hai. Chúng ta có thể trả về kết quả của hàm/tính toán như vậy thông qua phương thức bản đồ, do đó nó trả về một trình tạo mà chúng ta có thể lặp lại.

Trong trường hợp này, chức năng/tính toán cần được triển khai thông qua hàm lambda. Phần khó khăn là những gì chúng ta nhắm đến bên trong bản đồ và hàm lambda của nó.

hình thức chung của giải pháp đề xuất:

def function(gen1,gen2): 
     for item in map(lambda x, y: do_somethin(x,y), gen1, gen2): 
      yield item 
+2

Bạn nên cân nhắc việc đăng một số giải thích hữu ích về việc này thay vì chỉ là khối mã – AK47

1

Trong Python3 + bạn có thể làm:

def concat(a, b): 
    yield from a 
    yield from b 
Các vấn đề liên quan