Dav*_*Eyk 21 python merge iterator
我有两个迭代器,一个list和一个itertools.count对象(即无限值生成器).我想将这两个合并到一个生成的迭代器中,它将在两者之间交替屈服值:
>>> import itertools
>>> c = itertools.count(1)
>>> items = ['foo', 'bar']
>>> merged = imerge(items, c) # the mythical "imerge"
>>> merged.next()
'foo'
>>> merged.next()
1
>>> merged.next()
'bar'
>>> merged.next()
2
>>> merged.next()
Traceback (most recent call last):
...
StopIteration
Run Code Online (Sandbox Code Playgroud)
这样做最简单,最简洁的方法是什么?
Pra*_*mod 38
发电机可以很好地解决您的问题.
def imerge(a, b):
for i, j in itertools.izip(a,b):
yield i
yield j
Run Code Online (Sandbox Code Playgroud)
Dav*_*cke 15
你可以做一些几乎与@Pramod最初建议的事情相似的事情.
def izipmerge(a, b):
for i, j in itertools.izip(a,b):
yield i
yield j
Run Code Online (Sandbox Code Playgroud)
这种方法的优点是,如果a和b都是无限的,你就不会耗尽内存.
Tom*_*rly 11
我也同意不需要itertools.
但为什么要停在2?
def tmerge(*iterators):
for values in zip(*iterators):
for value in values:
yield value
Run Code Online (Sandbox Code Playgroud)
从0开始处理任意数量的迭代器.
更新:DOH!一位意见提供者指出,除非所有迭代器的长度相同,否则这将不起作用.
正确的代码是:
def tmerge(*iterators):
empty = {}
for values in itertools.izip_longest(*iterators, fillvalue=empty):
for value in values:
if value is not empty:
yield value
Run Code Online (Sandbox Code Playgroud)
是的,我只是用不等长的列表和一个包含{}的列表来尝试它.
Cla*_*diu 10
我会做这样的事情.这将是最节省时间和空间的,因为您不会有将对象压缩在一起的开销.这也将工作,如果这两个a和b是无限的.
def imerge(a, b):
i1 = iter(a)
i2 = iter(b)
while True:
try:
yield i1.next()
yield i2.next()
except StopIteration:
return
Run Code Online (Sandbox Code Playgroud)
您可以使用zip以及itertools.chain.这仅在第一个列表有限时才有效:
merge=itertools.chain(*[iter(i) for i in zip(['foo', 'bar'], itertools.count(1))])
Run Code Online (Sandbox Code Playgroud)
小智 5
我更喜欢另一种更简洁的方式:
iter = reduce(lambda x,y: itertools.chain(x,y), iters)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
17868 次 |
| 最近记录: |