Le moyen le plus simple de le faire est le suivant: cyclezip1
. C'est assez rapide pour la plupart des objectifs.
import itertools
def cyclezip1(it1, it2, count):
pairs = itertools.izip(itertools.cycle(iter1),
itertools.cycle(iter2))
return itertools.islice(pairs, 0, count)
Voici une autre mise en œuvre de ce qui est environ deux fois plus vite quand count
est nettement plus grand que le plus petit commun multiple de it1
et 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)
ici, nous profitons du fait que les paires pédalez après la première n
d'entre eux où n
est le moins Mutliple commun de len(it1)
et len(it2)
. Cela suppose bien entendu que les itérations sont des collections de sorte que demander leur longueur a tout son sens. Une autre optimisation qui peut être fait est de remplacer la ligne
pairs = itertools.islice(pairs, 0, lcm)
avec
pairs = list(itertools.islice(pairs, 0, lcm))
Ceci est loin d'être aussi dramatique d'une amélioration (environ 2% dans mes tests) et loin d'être aussi cohérente . cela nécessite également plus de mémoire. Si it1
et it2
étaient connus à l'avance pour être suffisamment petits pour que la mémoire supplémentaire soit négligeable, alors vous pourriez presser cette performance supplémentaire.
Il est intéressant de noter que la chose évidente à faire dans le cas d'une collection est environ quatre fois plus lente que la première option présentée.
def cyclezip3(co1, co2, count):
l1 = len(co1)
l2 = len(co2)
return ((co1[i%l1], co2[i%l2]) for i in xrange(count))
La simplicité gagne! – cwall