【问题标题】:How to merge multiple iterators to get a new iterator which will iterate over them randomly?如何合并多个迭代器以获得一个新的迭代器,该迭代器将随机迭代它们?
【发布时间】:2022-01-25 13:17:19
【问题描述】:

假设我有一个迭代器列表:

iterators = [ iter([2, 3, 4]), iter([7, 9]), iter([-1, -2, -3, -4]) ]

如何使用上述迭代器创建一个新的迭代器,以便在每个步骤中随机选择列表中存在的一个迭代器(尚未完成)并从中输出下一个元素?它应该一直输出元素,直到所有迭代器都完成。

因此,例如,如果新的迭代器是it_combined,我可能会在尝试对其进行迭代时得到以下输出

>>> for it in it_combined:
...     print(it, end=" ")
...
2 7 3 -1 4 -2 -3 -4 9

【问题讨论】:

  • 一般情况下你能创建迭代器吗?你看过itertools标准库模块文档中的例子吗?
  • @KarlKnechtel 我已经从this 页面阅读了有关迭代器的信息,但我还没有阅读itertools 库模块文档。我想我现在就去做
  • 我之所以问,是因为现在给出的答案对于那些了解相关技术的人来说是直截了当的。有时人们确实知道这些事情,只需要推动尝试即可。不过,如果您从这些答案中学到了一些新东西,那就更好了。

标签: python random iterator


【解决方案1】:

您可以使用random.choice 从列表中随机选择一个迭代器。然后,您必须确保在用完此迭代器后将其从列表中删除。

您可以使用generator 来实现迭代器的合并/采样:

import random

random.seed(42)


def combine_iterators(iterators):
    while iterators:
        it = random.choice(iterators)
        try:
            yield next(it)
        except StopIteration:
            iterators.remove(it)


merged_iterator = combine_iterators(
    [iter([2, 3, 4]), iter([7, 9]), iter([-1, -2, -3, -4])]
)
for x in merged_iterator:
    print(x, end=" ")

输出:

-1 2 3 -2 7 4 9 -3 -4

【讨论】:

  • 不幸的是,“简单”的方法并不等同。它不会保留来自同一迭代器的元素的相对顺序。
  • 啊,当然!你是对的。
  • @tlgs 添加了一个变体,如果您不喜欢它,请随时回滚。因为它与您的代码基本相同,不认为值得另一个“答案”
【解决方案2】:

这符合您的需要吗?

选择一个随机迭代器并打印其中一个值。一旦该迭代器抛出其异常,将其从列表中删除。继续,直到所有迭代器都消失。

import random
iterators = [ iter([2, 3, 4]), iter([7, 9]), iter([-1, -2, -3, -4]) ]

while len(iterators) > 0:
    which = random.randint(0, len(iterators)-1)
    it = iterators[which]
    try:
        print(next(it))
    except Exception:
        del iterators[which]

【讨论】:

  • 欢迎回到 Stack Overflow。作为复习,请阅读How to Answer,并尝试解释您在代码中采用的解决问题的方法。这不是代码编写服务;目标是回答问题,而不是满足 OP 的代码要求。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-23
  • 1970-01-01
  • 2020-01-21
  • 2022-11-14
  • 2021-10-05
  • 2016-07-24
相关资源
最近更新 更多