如何解决如何交错两个迭代器,其中x%的样本来自一个迭代器,而1-x%的样本来自另一个迭代器
说有两个迭代器:
def genA():
while True:
yield 1
def genB():
while True:
yield 2
gA = genA()
gB = genB()
根据this SO answer,可以使用itertools
recipes将它们 均匀 插入:
def cycle(iterable):
# cycle('ABCD') --> A B C D A B C D A B C D ...
saved = []
for element in iterable:
yield element
saved.append(element)
while saved:
for element in saved:
yield element
def roundrobin(*iterables):
"roundrobin('ABC','D','EF') --> A D E B F C"
# Recipe credited to George Sakkis
num_active = len(iterables)
nexts = cycle(iter(it).__next__ for it in iterables)
while num_active:
try:
for next in nexts:
yield next()
except StopIteration:
# Remove the iterator we just exhausted from the cycle.
num_active -= 1
nexts = cycle(islice(nexts,num_active))
aa = roundrobin(gA,gB)
next(aa)
因此next(aa)
每次都会移动迭代器的输出,因此一堆next
的调用将导致1,2,1,1
-50%
来自一个迭代器,而另一个50%
将来自另一个。
我想知道如何编码,以便x%
来自一个迭代器,(1-x)%
来自另一个迭代器。例如,第一个迭代器的75%
和另一个迭代器的25%
。
因此,多次致电next(combinedIterator)
会导致如下情况:
1 1 1 2 1 1 1 2 1 1 1 2
出于我的目的,输出是否像上面一样严格排序,或者输出是否由概率决定都无所谓。
解决方法
如果您可以采用确定性方法(据我从您的自我回答中了解),则可以添加一个参数,它是第一个迭代器的百分比,然后只需计算每个迭代器的“部分”即可。例如,如果您想从第一个迭代器中使用.75
-转换为:对于iterator1
中的每个三个元素,产生一个 iterator2
中的元素。
def interleave(itt1,itt2,itt1_per):
itt1_frac,total = itt1_per.as_integer_ratio()
itt2_frac = total - itt1_frac
while True:
for _ in range(itt1_frac):
yield next(itt1)
for _ in range(itt2_frac):
yield next(itt2)
newGen = interleave(gA,gB,.75)
for _ in range(12):
print(next(newGen),end=' ')
这将打印:
1 1 1 2 1 1 1 2 1 1 1 2
注意! 这仅适用于“不错”的分数。例如:将此功能与.6
一起使用意味着对于5,404,319,552,844,595
中的每个 iterator1
元素,将产生 3,602,879,701,896,397
来自iterator2
的元素。
解决此问题的一种方法 是将decimal.Decimal
与 string arguments :
from decimal import Decimal
def interleave(itt1,total = Decimal(str(itt1_per)).as_integer_ratio()
...
现在使用Decimal
意味着通过.6
会转化为更{strong>明智的元素:{em> {{1}中每个三个元素},则从iterator1
中产生两个元素。
使用以iterator2
作为参数的修订后的代码将打印:
.6
,
def genA():
while True:
yield 1
def genB():
while True:
yield 2
gA = genA()
gB = genB()
import random
def xyz(itt1,itt2):
while True:
if random.random() < .25:
yield next(itt1)
else:
yield next(itt2)
newGen = xyz(gA,gB)
next(newGen)
这适用于均匀分布。我不会选择这作为某人可能给出非概率性答案的答案。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。