为什么我不能在我的双版本中覆盖我的旧生成器?

2024-09-30 11:32:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我试着用here所描述的函数来解决一个中文难题(这是最后一个练习)。我的代码包含问题的描述,所以你可以看看。总之,我发现,当我使用两个生成器进行双重迭代时,第二个for循环会耗尽第二个生成器,我无法通过删除它并重置它来重新启动它,因为生成器的基本特性。如果不在迭代中进一步推动生成器,然后通过执行以下操作将其重置为先前的位置,则无法检查生成器是否已耗尽:

generator1 = (bla1 for bla1 in Bla1)
generator2 = (bla2 for bla2 in Bla2)

for bla1 in generator1:
    for bla2 in generator2:
        if next(generator) == StopIteration:
            generator2 = (bla2 for bla2 in Bla2)

我知道,我必须通过再次创建一个生成器来重新初始化它,但是看起来我不能把生成器放在一个变量中并成功地进行双重迭代。显然,生成器必须在每次进入循环时动态创建的“for i in…”行中指定。我的问题是,我想在一行上创建一个生成器,将它放入一个变量中,然后随意重置它,这样我就可以进行双重迭代,因为我使用的一些生成器非常长。你知道吗

'''
Question:

Write a program to solve a classic ancient Chinese puzzle: 
We count 35 heads and 94 legs among the chickens and rabbits in a farm.
How many rabbits and how many chickens do we have?

Strategy: Double iteration. Keep the number of one animal constant and
add more of the other until you either hit 94 legs or overshoot.
'''


def Chinese_puzzle(heads,legs):

    if legs%2 != 0:
        return 'There are no crippled animals on this farm.'

    for rabbits, r_legs in enumerate((leg*4 for leg in range(round(legs/4)))):
        for chickens, c_legs in enumerate((leg*2 for leg in range(round(legs/2)))):
            leggs = r_legs+c_legs
            hedds = rabbits+chickens
            if leggs == legs and hedds == heads:
                return {'Chickens':chickens,'Rabbits':rabbits}
            elif leggs > legs or hedds > heads:
                break

    return 'No permutation of rabbits and chickens exists for this number of legs and heads'


print(Chinese_puzzle(35,94))

我能在for循环中去掉这些巨大的生成器以获得更高的可读性吗?你知道吗

enumerate((leg*4 for leg in range(round(legs/4))))

就像我说的,你在做什么

Rabbits = enumerate((leg*4 for leg in range(round(legs/4))))

不适用于双重迭代。你知道吗


Tags: andofinforrange重置heads双重
2条回答

for bla2 in generator2:在迭代开始时,只对变量求值一次。迭代器保存在内部临时文件中,它不会每次都重新计算变量。你知道吗

您可以将其更改为:

while True:
    try:
        bla2 = next(generator2)
    except StopIteration:
        break

这相当于for循环,只是每次都对变量求值。你知道吗

我认为您需要的是如何重新生成内部生成器,而无需将创建它的调用与for循环放在同一行中。我认为最简单的方法是将定义generator2的行移到外循环中:

generator1 = whatever()  # this could be a long generator expression
for i in generator1:
    generator2 = whatever2()
    for j in generator2:
        ...

由于许多原因,您当前的代码无法工作。其中,next没有return一个StopIteration,它提出了一个例外。但是没有理由尝试在内部循环中调用next,您只需要在外部循环的每次迭代中重新创建耗尽的生成器。你知道吗

但是正如jasonharper评论的那样,这个问题实际上不需要两个嵌套循环。首先,让我们尝试一个循环。你所需要做的就是计算鸡和鸡腿的数量,这样你就可以计算出给定数量的兔子的总数(当你循环计算这个数字时)。然后检查腿是否是双头的。如果是这样,你已经找到了解决办法。你知道吗

for rabbits in range(heads+1):
    r_legs = rabbits * 4
    chickens = heads - rabbits
    c_legs = legs - r_legs
    if c_legs == chickens * 2:
        return {"Rabbits": rabbits, "Chickens": chickens}

但是你可以更进一步,不用外环。首先假设所有的头都是鸡的。每只鸡有一对腿。我们可以很容易地计算出多了多少对腿。每多出一对,其中一个头就属于兔子而不是鸡。你知道吗

def Chinese_puzzle(heads,legs):
    rabbits = legs // 2 - heads
    chickens = heads - rabbits
    return {"Rabbits": rabbits, "Chickens": chickens}

我没有做任何精神检查,但你可能只需要检查腿的奇数,或鸡或兔子的负数。我建议在这些情况下引发异常,而不是返回错误消息字符串。你知道吗

相关问题 更多 >

    热门问题