python 没有重复的 itertools 循环
python itertools round robin with no duplications
我在 https://docs.python.org/3.1/library/itertools.html
中成功修改了 roundrobin 的配方
包括限制(到达 X 元素时停止)- 下面的代码...
现在 - 我真正想要的是 "stop when reaching X elements but with no element duplication"。
有可能吗? (因为是发电机...)
def roundrobin(limit, *iterables):
"roundrobin('ABC', 'D', 'EF') --> A D E B F C"
# Recipe credited to George Sakkis
pending = len(iterables)
nexts = cycle(iter(it).next for it in iterables)
while pending:
try:
for next in nexts:
yield next()
limit -= 1
if limit == 0:
return
except StopIteration:
pending -= 1
nexts = cycle(islice(nexts, pending))
调用它:
candidates = [['111', '222', '333'],['444','222','555']]
list(roundrobin(4, *candidates))
我想得到:
['111,'444','222','333']
而不是:
['111,'444','222','222']
就像我正在使用当前代码一样
这是一种可能的实现方式 - 我在生成器函数中添加了一个名为 seen
的 set
,以跟踪我们已经 yield
编辑的元素。请注意,这意味着 all 中的元素 every iterable
必须是 hashable(如果它们达到),这不是基数的限制 roundrobin
.
def roundrobin_limited_nodupe(limit, *iterables):
"""A round-robin iterator duplicates removed and a limit.
>>> list(roundrobin_limited_nodupe(6, 'ABC', 'DB', 'EFG'))
['A', 'D', 'E', 'B', 'F', 'C'] # only six elements, only one 'B'
Notes:
- Recipe credited to George Sakkis
"""
pending = len(iterables)
seen = set() # keep track of what we've seen
nexts = cycle(iter(it).next for it in iterables)
while pending:
try:
for next in nexts:
candidate = next()
if candidate not in seen: # only yield when it's new
seen.add(candidate)
yield candidate
limit -= 1
if limit == 0:
return
except StopIteration:
pending -= 1
nexts = cycle(islice(nexts, pending))
我在 https://docs.python.org/3.1/library/itertools.html
中成功修改了 roundrobin 的配方
包括限制(到达 X 元素时停止)- 下面的代码...
现在 - 我真正想要的是 "stop when reaching X elements but with no element duplication"。
有可能吗? (因为是发电机...)
def roundrobin(limit, *iterables):
"roundrobin('ABC', 'D', 'EF') --> A D E B F C"
# Recipe credited to George Sakkis
pending = len(iterables)
nexts = cycle(iter(it).next for it in iterables)
while pending:
try:
for next in nexts:
yield next()
limit -= 1
if limit == 0:
return
except StopIteration:
pending -= 1
nexts = cycle(islice(nexts, pending))
调用它:
candidates = [['111', '222', '333'],['444','222','555']]
list(roundrobin(4, *candidates))
我想得到:
['111,'444','222','333']
而不是:
['111,'444','222','222']
就像我正在使用当前代码一样
这是一种可能的实现方式 - 我在生成器函数中添加了一个名为 seen
的 set
,以跟踪我们已经 yield
编辑的元素。请注意,这意味着 all 中的元素 every iterable
必须是 hashable(如果它们达到),这不是基数的限制 roundrobin
.
def roundrobin_limited_nodupe(limit, *iterables):
"""A round-robin iterator duplicates removed and a limit.
>>> list(roundrobin_limited_nodupe(6, 'ABC', 'DB', 'EFG'))
['A', 'D', 'E', 'B', 'F', 'C'] # only six elements, only one 'B'
Notes:
- Recipe credited to George Sakkis
"""
pending = len(iterables)
seen = set() # keep track of what we've seen
nexts = cycle(iter(it).next for it in iterables)
while pending:
try:
for next in nexts:
candidate = next()
if candidate not in seen: # only yield when it's new
seen.add(candidate)
yield candidate
limit -= 1
if limit == 0:
return
except StopIteration:
pending -= 1
nexts = cycle(islice(nexts, pending))