给定:
x = ['a','b','c','d','e']
y = ['1','2','3']
我想迭代导致:
a, 1
b, 2
c, 3
d, 1
e, 2
a, 3
b, 1
...其中两个迭代器独立循环直到给定计数。
Python 的循环(可迭代的)可以通过 1 个可迭代的来做到这一点。 map 和 itertools.izip_longest 等函数可以带一个函数来处理 None,但不提供内置的自动重复。
一个不太狡猾的想法是将每个列表连接到我可以均匀迭代的特定大小。 (嘘!)
建议?提前致谢。
请您参考如下方法:
执行此操作的最简单方法是在下面的 cyclezip1 中。对于大多数用途来说,它足够快。
import itertools
def cyclezip1(it1, it2, count):
pairs = itertools.izip(itertools.cycle(iter1),
itertools.cycle(iter2))
return itertools.islice(pairs, 0, count)
这是它的另一种实现,当 count 明显大于 it1 和 it2 的最小公倍数时,它的速度大约是原来的两倍.
import fractions
def cyclezip2(co1, co2, count):
l1 = len(co1)
l2 = len(co2)
lcm = l1 * l2 / float(fractions.gcd(l1, l2))
pairs = itertools.izip(itertools.cycle(co1),
itertools.cycle(co2))
pairs = itertools.islice(pairs, 0, lcm)
pairs = itertools.cycle(pairs)
return itertools.islice(pairs, 0, count)
这里我们利用了这样一个事实,即对将在它们的第一个 n 之后循环,其中 n 是 len(it1)< 的最小公倍数 和 len(it2)。这当然假设可迭代对象是集合,因此询问它们的长度是有意义的。可以进行的进一步优化是 替换行
pairs = itertools.islice(pairs, 0, lcm)
与
pairs = list(itertools.islice(pairs, 0, lcm))
这并没有那么显着的改进(在我的测试中大约为 2%),也没有那么一致。它还需要更多内存。如果事先知道 it1 和 it2 足够小,以至于额外的内存可以忽略不计,那么您就可以从中挤出额外的性能。
有趣的是,在集合的情况下,显然要做的事情比第一个选项慢四倍。
def cyclezip3(co1, co2, count):
l1 = len(co1)
l2 = len(co2)
return ((co1[i%l1], co2[i%l2]) for i in xrange(count))
