假设:
x = ['a','b','c','d','e']
y = ['1','2','3']
我想迭代导致:
a, 1
b, 2
c, 3
d, 1
e, 2
a, 3
b, 1
...两个iterables独立循环直到给定的计数。
Python的循环(可迭代)可以做到这一点w / 1 iterable。 map和itertools.izip_longest等函数可以使用函数来处理None,但不提供内置的自动重复。
一个不那么狡猾的想法是将每个列表连接到一定的大小,我可以从中均匀地迭代。 (Boooo!)
连连呢?提前谢谢。
答案 0 :(得分:10)
最简单的方法是在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
的{{1}}之后循环,其中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))
答案 1 :(得分:7)
import itertools
x = ['a','b','c','d','e']
y = ['1','2','3']
for a, b in itertools.izip(itertools.cycle(x), itertools.cycle(y)):
print a, b