2008-12-20 8 views
6

J'utilise Python pour infiniment parcourir une liste, en répétant chaque élément de la liste un certain nombre de fois. Par exemple donné la liste:Comment parcourir une liste en répétant chaque élément en Python

l = [1, 2, 3, 4] 

Je voudrais sortie chaque élément deux fois, puis répéter le cycle:

1, 1, 2, 2, 3, 3, 4, 4, 1, 1, 2, 2 ... 

J'ai une idée de l'endroit où commencer:

def cycle(iterable): 
    if not hasattr(cycle, 'state'): 
    cycle.state = itertools.cycle(iterable) 
    return cycle.next() 

>>> l = [1, 2, 3, 4] 
>>> cycle(l) 
1 
>>> cycle(l) 
2 
>>> cycle(l) 
3 
>>> cycle(l) 
4 
>>> cycle(l) 
1 

Mais comment pourrais-je répéter chaque élément?

Modifier

Pour clarifier cela devrait itérer infiniment. J'ai aussi utilisé la répétition de l'élément deux fois comme l'exemple le plus court - Je voudrais vraiment répéter chaque élément n fois.

Mise à jour

Est-ce que votre solution me conduire à ce que je cherchais:

>>> import itertools 
>>> def ncycle(iterable, n): 
... for item in itertools.cycle(iterable): 
...  for i in range(n): 
...  yield item 
>>> a = ncycle([1,2], 2) 
>>> a.next() 
1 
>>> a.next() 
1 
>>> a.next() 
2 
>>> a.next() 
2 
>>> a.next() 
1 
>>> a.next() 
1 
>>> a.next() 
2 
>>> a.next() 
2 

Merci pour les réponses rapides!

+0

quand vous voulez arrêter? –

Répondre

13

Que diriez-vous ceci:

import itertools 

def bicycle(iterable, repeat=1): 
    for item in itertools.cycle(iterable): 
     for _ in xrange(repeat): 
      yield item 

c = bicycle([1,2,3,4], 2) 
print [c.next() for _ in xrange(10)] 

EDIT: incorporé bishanty's répétition paramètre de comptage et Adam Rosenfield's list comprehension.

+0

>>> importer itertools >>> def ncycle (iterable, n): ... pour objet dans itertools.cycle (iterable): ... pour moi dans la gamme (n): ... afficher le produit –

+0

C'est une si douce réponse. Je voudrais pouvoir faire +10. – PEZ

1

solution doit être quelque chose comme

iterable = [1, 2, 3, 4] 
n = 2 

while (True): 
    for elem in iterable: 
    for dummy in range(n): 
     print elem # or call function, or whatever 

Edit: ajouté 'while (true)' à itérer indéfiniment.

6

Vous pouvez le faire avec un générateur assez facilement:

def cycle(iterable): 
    while True: 
     for item in iterable: 
      yield item 
      yield item 

x=[1,2,3] 
c=cycle(x) 

print [c.next() for i in range(10)] // prints out [1,1,2,2,3,3,1,1,2,2] 
+0

Encore une fois, je ne suis pas sûr à 100% d'avoir compris la question, mais les générateurs ne sont-ils pas un peu exagérés pour un problème simple comme le retour d'un article deux fois (ou n fois)? –

+0

C'est 5 lignes. Comment cela peut-il être exagéré? Et si l'alternative est de construire une liste, c'est impossible, parce que c'est une longueur infinie. – recursive

+0

Pourquoi créer une fonction en premier lieu? Vous pouvez atteindre les mêmes résultats avec une simple boucle imbriquée, sans avoir besoin d'un générateur, En lisant la boucle, même un novice comprend immédiatement la signification du code, alors qu'avec les générateurs vous devez faire confiance au nom de la fonction. –

0
[ "%d, %d" % (i, i) for i in [1, 2, 3, 4] * 4] 

Les 4 derniers il y a le nombre de cycles.

1
import itertools as it 

def ncycle(iterable, n=1): 
    if n == 1: 
     return it.cycle(iterable) 
    return it.cycle(it.chain(*it.izip(*([iterable]*n)))) 
0
itertools.chain.from_iterable(itertools.repeat(item, repeat) for item in itertools.cycle(l)) 
0

je le fais de cette façon:

from itertools import cycle, repeat, chain 
flatten = chain.from_iterable # better name 

def ncycle(xs, n): 
    return flatten(repeat(x, n) for x in cycle(xs)) 

# example 
for n,x in enumerate(ncycle('abcd', 2)): 
    print(x, end=" ") 
    if n > 9: 
     print("") 
     break 
# output: a a b b c c d d a a b 
Questions connexes