2012-06-25 26 views
20

Tôi có một chức năng mang lại kết quả khi tải xuống. Theo mục đích của câu hỏi này, cho phép nói tôi tạo ra một chích một lần thứ hai nhưng tôi muốn có một chức năng thuận tiện để quấn máy phát điện của tôi:Làm cách nào để mang lại kết quả từ hàm tạo bộ tạo Python lồng nhau?

import time 

def GeneratorFunction(max_val): 
    for i in range(0,5): 
     time.sleep(1) 
     yield "String %d"%i 

def SmallGenerator(): 
    yield GeneratorFunction(3) 

for s in SmallGenerator(): 
    print s 

... tại sao không mà chỉ in 5 chuỗi Tôi mong đợi? Thay vào đó nó xuất hiện để trả về trình tạo functio:

<generator object GeneratorFunction at 0x020649B8> 

Làm cách nào để tạo chuỗi như một chức năng tạo bình thường?

+7

FYI, bằng Python 3.3, 'năng suất từ ​​GeneratorFunction (3)' sẽ làm việc .. – DSM

+0

@DSM: Cảm ơn . Vẫn chưa thực hiện quá trình chuyển đổi sang 3+ ... –

Trả lời

33

SmallGenerator cần phải được một cái gì đó xung quanh:

def SmallGenerator(): 
    for item in GeneratorFunction(3): 
     yield item 

Trong thực hiện của bạn SmallGenerator mang lại một máy phát điện thực tế, không phải là mặt hàng được tạo ra bởi nó .

+0

Vì vậy, đó là lý do tại sao câu trả lời tôi đăng hoạt động? Bởi vì nó quay trở lại một máy phát điện thay vì sinh lời? –

+0

@JonCage Có. Lời giải thích của tôi thực sự sai. Tôi đã có nghĩa là để nói "sản lượng" chứ không phải là "trả về". Tôi sẽ chỉnh sửa nó. Trả lại chính máy phát điện hoạt động (như trong câu trả lời của bạn). Tuy nhiên, khi bạn đang gói một máy phát điện, bạn sẽ muốn áp dụng một số loại chức năng trên mỗi mục mà nó sẽ tạo ra. –

+0

@loan: Vâng, tôi thấy rằng bây giờ - cảm ơn vì lời giải thích. Sẽ trả về chức năng của máy phát chứ không phải lặp lại và cho mỗi kết quả lần thứ hai nhanh hơn? –

15

Không thể tin rằng tôi đã bỏ lỡ điều này; Câu trả lời chỉ đơn giản là trả lại chức năng máy phát điện với các đối số thích hợp áp dụng:

import time 

def GeneratorFunction(max_val): 
    for i in range(0,max_val): 
     time.sleep(1) 
     yield "String %d"%i 

def SmallGenerator(): 
    return GeneratorFunction(3) # <-- note the use of return instead of yield 

for s in SmallGenerator(): 
    print s 
10

Bạn có thể phải sử dụng new yield from, có sẵn từ Python 3.3, được gọi là “delegated generator”.

Nếu tôi hiểu chính xác câu hỏi, tôi đã gặp vấn đề tương tự và tìm thấy câu trả lời ở nơi khác.

tôi muốn làm một cái gì đó như thế này:

def f(): 

    def g(): 

     do_something() 
     yield x 
     … 
     yield y 

    do_some_other_thing() 
    yield a 
    … 
    g() # Was not working. 
    yield g() # Was not what was expected neither; yielded None. 
    … 
    yield b 

bây giờ tôi sử dụng này để thay thế:

yield from g() # Now it works, it yields x and Y. 

tôi có câu trả lời từ trang này: Python 3: Using "yield from" in Generators - Part 1 (simeonvisser.com).

1

Đến đây tìm kiếm một dạng "sản lượng lồng nhau" khác và cuối cùng tìm thấy câu trả lời ẩn. Có thể không phải là tốt nhất nhưng nó hoạt động.

Tôi đã muốn kiếm thông qua một cây đăng ký và đây là giải pháp.

 def genKeys(key): 
      for value in key.values(): 
       yield value 
      for subkey in key.subkeys(): 
       print(subkey) 
       for x in genKeys(subkey): #this is the trick 
        continue 
0

Dưới đây là một ví dụ nhỏ để tạo ra các bảng cửu chương 1-10:

class Gen1: 

    def __init__(self, gen2): 
     self.gen2 = gen2 

    def __iter__(self):  
     for a in range(1, 11):  
      for b in self.gen2: 
       yield a * b 


class Gen2:  

    def __iter__(self): 
     for a in range(1, 11): 
      yield a 


def main(): 

    gen2 = Gen2() 
    gen1 = Gen1(gen2) 

    for v in gen1: 
     print(v) 

if __name__ == '__main__': 
    main()