如何用itertools生成无限序列

发布于 2025-01-21 17:33:58 字数 359 浏览 1 评论 0原文

我想生成两个0和1的不定式系列,特别是按以下顺序生成:

0、1、0,-1、0、1、0,-1,...

我创建了以下代码,该代码未返回除了:

# for in loop
for i in itertools.cycle(range(0,2)):
    if i == 0:
        i += 1
        if i == 1:
            i -= 1
            if i == 0:
                i -= 1
                print(i, end = " ")

它只是返回一系列-1。无法弄清楚错误在哪里。任何人都可以给任何建议吗

I would like to generate two infinitive series of 0 and 1 and specifically in the following order:

0, 1, 0, -1, 0, 1, 0, -1, ...

I have created the following code which does not return what except:

# for in loop
for i in itertools.cycle(range(0,2)):
    if i == 0:
        i += 1
        if i == 1:
            i -= 1
            if i == 0:
                i -= 1
                print(i, end = " ")

It just returns a series of -1. Cannot figure out where the error is. Can anyone give any suggestions

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

热情消退 2025-01-28 17:33:59

您可以使用 itertools.cycles.cycle() 以明确说明要生成的元素的方式:

from itertools import cycle
cycle([0, 1, 0, -1])

You can use itertools.cycle() in a way that explicitly states the elements you want to generate:

from itertools import cycle
cycle([0, 1, 0, -1])
季末如歌 2025-01-28 17:33:59

作为替代方案,您可以使用一些简单的模块化算术来实现自己的发电机:

def seq():
    i = 0
    while True:
        yield (-1)**(i // 2) * (i % 2)
        i = (i + 1) % 4  # keeps i small, so as not to take up too much memory

演示:

>>> s = seq()
>>> [next(s) for _ in range(10)]
[0, 1, 0, -1, 0, 1, 0, -1, 0, 1]

我知道OP指出,他们特别想使用Itertools,但这仍然可能对他人有帮助。

正如评论中指出的那样,您也可以简单地模拟itertools.cycle通过传递任意args并使用的收益率(请注意itertools.cycles.cycle实际上,在引擎盖下的工作方式不同):

def seq(*args):
    while True:
        yield from args


s = seq(0, 1, 0, -1)

但是,在我看来,这并不像弄清楚实际算术序列那样有趣:D

As an alternative, you can implement your own generator with some simple modular arithmetic:

def seq():
    i = 0
    while True:
        yield (-1)**(i // 2) * (i % 2)
        i = (i + 1) % 4  # keeps i small, so as not to take up too much memory

Demo:

>>> s = seq()
>>> [next(s) for _ in range(10)]
[0, 1, 0, -1, 0, 1, 0, -1, 0, 1]

I know OP states that they specifically want to use itertools, but this may still be helpful to others.

As pointed out in a comment, you can also simply emulate itertools.cycle by passing arbitrary args and using yield from (note that itertools.cycle actually works differently under the hood):

def seq(*args):
    while True:
        yield from args


s = seq(0, 1, 0, -1)

But that's not as fun as figuring out the actual arithmetic sequence in my opinion :D

擦肩而过的背影 2025-01-28 17:33:59

不确定为什么您要坚持使用itertools.cycle在这样的循环中,但这是您可以做这项工作的一种方法:

for i in itertools.cycle(range(0, 2)):
    if i == 0:
        print(i, end=" ")
        i += 1
        print(i, end=" ")
        i -= 1
        print(i, end=" ")
        i -= 1
        print(i, end=" ")

请注意,确实没有意义使用嵌套如果语句,因为每个嵌套谓词将始终为真:如果i为零,然后您添加一个,则当然您的嵌套谓词如果i == 1是正确的...

此外,您对itertools.cycles.cycle在 for 中的使用是一个反模式。如BrokenBenchmark的答案所示,您可以永远循环序列本身的元素。如果您坚持使用对循环使用

for i in itertools.cycle([0, 1, 0, -1]):
    print(i, end=" ")

但是,这种方法有很多错误。也就是说,正如我在评论中所讨论的那样,这是一个无限 loop ,它与无限 序列 。有了一个无限的循环,再也不会发生任何其他事情 - 您的程序将永远被骑自行车在您的四个要素上骑自行车,无法做任何其他事情。

如果您使用itertools.cycle作为生成器,则可以随时在序列中关闭的位置,允许您执行其他任务按照您想要的序列,如您所需的那样:

c = itertools.cycle((0, 1, 0, -1))
next(c) # 0
next(c) # 1
next(c) # 0
next(c) # -1

# do something else for a while
next(c) # 0

# yield the next 10 items from the sequence
for _ in range(10):
    print(next(c), end=" ")

# do something else again

Not sure why you're insisting on using itertools.cycle in a for loop like this, but here's one way you could make this work:

for i in itertools.cycle(range(0, 2)):
    if i == 0:
        print(i, end=" ")
        i += 1
        print(i, end=" ")
        i -= 1
        print(i, end=" ")
        i -= 1
        print(i, end=" ")

Note that there's really no point in using your nested if statements, since each nested predicate will always be true: if i is zero, and then you add one to it, then of course your nested predicate if i == 1 will be true...

In addition, your use of itertools.cycle in a for loop is an anti-pattern. As shown in BrokenBenchmark's answer, you can simply cycle over the elements of the sequence itself, forever. If you insist on using the for loop:

for i in itertools.cycle([0, 1, 0, -1]):
    print(i, end=" ")

There are so many things wrong with this approach though. Namely, as I discussed in the comments, this is an infinite loop which is a fundamentally different behavior than an infinite sequence. With an infinite loop, nothing else can ever happen -- your program will be stuck cycling over your four elements forever with no way to do anything else.

If you use itertools.cycle as it's meant to be used -- as a generator -- you can pick up where you left off in the sequence at any time, allowing you to perform other tasks for as long as you want before continuing your sequence:

c = itertools.cycle((0, 1, 0, -1))
next(c) # 0
next(c) # 1
next(c) # 0
next(c) # -1

# do something else for a while
next(c) # 0

# yield the next 10 items from the sequence
for _ in range(10):
    print(next(c), end=" ")

# do something else again
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文