Python嵌套生成器无法正常工作

时间:2018-03-09 23:12:43

标签: python generator

我正在练习发电机,我想知道为什么下面的代码不能打印16对但只有4对。

WIN32_FIND_DATAW

输出

FindClose

虽然我期望的输出是

def range_generator_function(my_range):
    for i in my_range:
        yield i

gen1=range_generator_function(range(1,5))
gen2=range_generator_function(range(1,5))

def pairs_generator_function(gen1,gen2):
    for it1 in gen1:
        for it2 in gen2:
            yield [it1,it2]

my_gen = pairs_generator_function(gen1,gen2)

for it in my_gen:
    print(it)

5 个答案:

答案 0 :(得分:5)

实际输出是正确的。您的gen2实例已被第一个内循环完全耗尽:

def pairs_generator_function(gen1,gen2):
    for it1 in gen1:
        for it2 in gen2:  # <--- this consumes gen2
            yield [it1,it2]

在随后的迭代中,再次迭代gen2为空。

答案 1 :(得分:2)

第一次通过内循环后,你耗尽了gen2。您不再拥有该流中的任何内容,因此gen2的其他三个值与配对无关。您需要每次都重新启动itertools.tee。考虑 <section id="em_widget-6" class="widget widget_em_widget"><ul><li class="haekken-event"><a href="https://www.haekken.de/events/pale-seas/" class="event-link"><div class="event-info"><div><h2><span>Pale Seas &#8211; verlegt!</span></h2><p class="event-meta">09_März | <span style="text-transform: uppercase;">Live</span></p></div></div><img src="https://www.haekken.de/wp-content/uploads/PALE-SEAS-_online.jpg" alt="Event-Foto"/></a></li><li class="haekken-event"><a href="https://www.haekken.de/events/banfi/" class="event-link"><div class="event-info"><div><h2><span>Banfi</span></h2><p class="event-meta">13_März | <span style="text-transform: uppercase;">Live</span></p></div></div><img src="https://www.haekken.de/wp-content/uploads/banfi_press_online.jpg" alt="Event-Foto"/></a></li><li class="haekken-event"><a href="https://www.haekken.de/events/2908/" class="event-link"><div class="event-info"><div><h2><span>Kiez Treats &#8211; Binkbeats</span></h2><p class="event-meta">15_März | <span style="text-transform: uppercase;">Live</span></p></div></div><img src="https://www.haekken.de/wp-content/uploads/binkbeats_press_online.jpg" alt="Event-Foto"/></a></li><li class="haekken-event"><a href="https://www.haekken.de/events/mynth/" class="event-link"><div class="event-info"><div><h2><span>Mynth</span></h2><p class="event-meta">16_März | <span style="text-transform: uppercase;">Live</span></p></div></div><img src="https://www.haekken.de/wp-content/uploads/de-0419-826366-back.jpg" alt="Event-Foto"/></a></li><li class="haekken-event"><a href="https://www.haekken.de/events/noah-gundersen/" class="event-link"><div class="event-info"><div><h2><span>Noah Gundersen</span></h2><p class="event-meta">17_März | <span style="text-transform: uppercase;">Live</span></p></div></div><img src="https://www.haekken.de/wp-content/uploads/noah_gundersen_online.jpg" alt="Event-Foto"/></a></li><li class="haekken-event"><a href="https://www.haekken.de/events/garden-city-movement/" class="event-link"><div class="event-info"><div><h2><span>Garden City Movement &#8211; verlegt!!!</span></h2><p class="event-meta">19_März | <span style="text-transform: uppercase;">Live</span></p></div></div><img src="https://www.haekken.de/wp-content/uploads/Garden-City-Movement_online.jpg" alt="Event-Foto"/></a></li><li class="haekken-event"><a href="https://www.haekken.de/events/trails/" class="event-link"><div class="event-info"><div><h2><span>Trails</span></h2><p class="event-meta">21_März | <span style="text-transform: uppercase;">Live</span></p></div></div><img src="https://www.haekken.de/wp-content/uploads/TRAILS_online.jpg" alt="Event-Foto"/></a></li><li class="haekken-event"><a href="https://www.haekken.de/events/james-chatburn-wayne-snow/" class="event-link"><div class="event-info"><div><h2><span>James Chatburn &#038; Wayne Snow</span></h2><p class="event-meta">22_März | <span style="text-transform: uppercase;">Live</span></p></div></div><img src="https://www.haekken.de/wp-content/uploads/chatburn_snow_online.jpg" alt="Event-Foto"/></a></li><li class="haekken-event"><a href="https://www.haekken.de/events/amy-shark/" class="event-link"><div class="event-info"><div><h2><span>Amy Shark &#8211; AUSVERKAUFT!</span></h2><p class="event-meta">26_März | <span style="text-transform: uppercase;">Live</span></p></div></div><img src="https://www.haekken.de/wp-content/uploads/AmyShark_Pressshot12018_online.jpg" alt="Event-Foto"/></a></li><li class="haekken-event"><a href="https://www.haekken.de/events/hippie-sabotage/" class="event-link"><div class="event-info"><div><h2><span>Hippie Sabotage</span></h2><p class="event-meta">27_März | <span style="text-transform: uppercase;">Live</span></p></div></div><img src="https://www.haekken.de/wp-content/uploads/Hippiesabotage_online.jpg" alt="Event-Foto"/></a></li><li class="haekken-event"><a href="https://www.haekken.de/events/me-reas/" class="event-link"><div class="event-info"><div><h2><span>Me &#038; Reas</span></h2><p class="event-meta">28_März | <span style="text-transform: uppercase;">Live</span></p></div></div><img src="https://www.haekken.de/wp-content/uploads/Me-Reas_1_©-David-Häuser_online.jpg" alt="Event-Foto"/></a></li><li class="haekken-event"><a href="https://www.haekken.de/events/projectbeatmaker-spring-session/" class="event-link"><div class="event-info"><div><h2><span>Project:Beatmaker &#8211; Spring Session</span></h2><p class="event-meta">30_März | <span style="text-transform: uppercase;">Club</span></p></div></div><img src="https://www.haekken.de/wp-content/uploads/projectbeatmaker_logo.png" alt="Event-Foto"/></a></li><li class="haekken-event"><a href="https://www.haekken.de/events/kiez-treats-peter-broderick/" class="event-link"><div class="event-info"><div><h2><span>Kiez Treats &#8211; Peter Broderick</span></h2><p class="event-meta">12_April | <span style="text-transform: uppercase;">Live</span></p></div></div><img src="https://www.haekken.de/wp-content/uploads/Peter-7-by-Declan-Kelly_online.jpg" alt="Event-Foto"/></a></li><li class="haekken-event"><a href="https://www.haekken.de/events/holly-miranda/" class="event-link"><div class="event-info"><div><h2><span>Holly Miranda</span></h2><p class="event-meta">13_April | <span style="text-transform: uppercase;">Live</span></p></div></div><img src="https://www.haekken.de/wp-content/uploads/holly-miranda-750_0.jpg" alt="Event-Foto"/></a></li><li class="haekken-event"><a href="https://www.haekken.de/events/glode/" class="event-link"><div class="event-info"><div><h2><span>Gløde</span></h2><p class="event-meta">14_April | <span style="text-transform: uppercase;">Live</span></p></div></div><img src="https://www.haekken.de/wp-content/uploads/BY-JULIEN-FERTL2_online.jpg" alt="Event-Foto"/></a></li><li class="haekken-event"><a href="https://www.haekken.de/events/this-is-the-kit/" class="event-link"><div class="event-info"><div><h2><span>This Is The Kit</span></h2><p class="event-meta">20_April | <span style="text-transform: uppercase;">Live</span></p></div></div><img src="https://www.haekken.de/wp-content/uploads/thisisthekit_online.jpg" alt="Event-Foto"/></a></li><li class="haekken-event"><a href="https://www.haekken.de/events/marvin-brooks/" class="event-link"><div class="event-info"><div><h2><span>Marvin Brooks</span></h2><p class="event-meta">21_April | <span style="text-transform: uppercase;">Live</span></p></div></div><img src="https://www.haekken.de/wp-content/uploads/Marvin-Brooks1_NICULAI_CONSTANTINESCU_PHOTOGRAPY_online.jpg" alt="Event-Foto"/></a></li><li class="haekken-event"> 克隆更多副本。

答案 2 :(得分:1)

您获得的输出是由于在第二次迭代中,生成器gen2已用尽。

您可以在循环之前使用list来存储其输出,或者在每次迭代时使用itertools.tee复制它。前者无法处理无限生成器,但在实现后者之前,让我指出您实际上正在重新实现itertools.product

from itertools import product

my_gen = product(gen1, gen2)

for it in my_gen:
    print(it)

答案 3 :(得分:0)

我修改了代码以便获得所需的输出,现在每次在外部循环中重新创建生成器。

def range_generator_function(my_range):
    for i in my_range:
        yield i

def pairs_generator_function():
    gen1=range_generator_function(range(1,5))
    for it1 in gen1:
        gen2=range_generator_function(range(1,5))
        for it2 in gen2:
            yield [it1,it2]

my_gen = pairs_generator_function()

for it in my_gen:
    print(it)

答案 4 :(得分:0)

正如@wim指出的那样,在第一次迭代后你的生成器完全耗尽了。但是,为了防止这种情况,请将gen2pairs_generator_function作为列表传递给itertools.tee。但是,您可以使用import itertools def range_generator_function(my_range): for i in my_range: yield i gen1=range_generator_function(range(1,5)) gen2=range_generator_function(range(1,5)) def pairs_generator_function(gen1,gen2): for it1 in gen1: for it2 in gen2: yield [it1,it2] gen1, gen1_l = itertools.tee(gen1) gen2, gen2_l = itertools.tee(gen2) print(list(pairs_generator_function(list(gen1_l), list(gen2_l)))) 存储原始生成器的两个副本:一个用于作为列表传递给函数,另一个用于将来使用:

[[1, 1], [1, 2], [1, 3], [1, 4], [2, 1], [2, 2], [2, 3], [2, 4], [3, 1], [3, 2], [3, 3], [3, 4], [4, 1], [4, 2], [4, 3], [4, 4]]

输出:

gen1

但请注意,>>next(gen1) 1 >>next(gen2) 1 和gen2`仍然指向内存中的项目:

public abstract class EO {
    @Autowired
    protected SmsNotificationService smsNotificationService;
    @Autowired
    protected SendEmailService sendEmailService;
    ...
    protected abstract void executeOperation(GenericMessage gMessage);
}

public final class OperationsExecutor {
    public enum OperationsType {
        ENROLL, CAMPAIGN
    }

    private OperationsExecutor() {
    }

    public static Object delegateOperation(OperationsType type, Object obj) 
    {
        switch(type) {
            case ENROLL:
                if (obj == null) {
                    return new EnrollOperation();
                }
                return EnrollOperation.validateRequestParams(obj);
            case CAMPAIGN:
                if (obj == null) {
                    return new CampaignOperation();
                }
                return CampaignOperation.validateRequestParams(obj);
            default:
                throw new IllegalArgumentException("OperationsType not supported.");
        }
    }
}

@Configurable(dependencyCheck = true)
public class CampaignOperation extends EO {
    @Override
    public void executeOperation(GenericMessage genericMessage) {
        LOGGER.info("This is CAMPAIGN Operation: " + genericMessage);
    }
}