2015-10-07 3 views
2

Dites que vous avez une liste et que vous avez un point de départ (par exemple le 3e index). Comment allez-vous parcourir la liste commençant à cet index, et revenir en arrière pour visiter tous les éléments de la liste? Cela signifie que vous pouvez commencer votre itération au milieu de la liste, mais une fois que vous avez atteint la fin, vous continuerez depuis le début jusqu'à ce que tous les éléments de la liste aient été visités. Quelle est la manière la plus propre et la plus efficace de faire quelque chose comme ça? Idéalement, je cherche quelque chose d'efficace à un pseudo python for x in list starting with i:.Itérer dans une liste à partir d'un point de départ

Répondre

1

Si votre liste est grande et que vous voulez éviter de copier des parties de la liste, vous devez utiliser un itérateur personnalisé:

def starting_with(arr, start_index): 
    # use xrange instead of range in python 2 
    for i in range(start_index, len(arr)): 
     yield arr[i] 
    for i in range(start_index): 
     yield arr[i] 

for value in starting_with(my_list, 3): 
    ... 
2

Pour revenir autour (sans itertools), vous devez utiliser le reste de l'opérateur de division:

i = start_index 
while i < len(mylist) + start_index: 
    print mylist[i % len(mylist)] 
    i+=1 

Ou mieux encore, comme l'a souligné @jonrsharpe:

for idx in range(len(mylist)): 
    print mylist[(idx + start_index) % len(mylist)] 

Pour Par souci d'exhaustivité, et parce que le générateur sera plus efficace dans ce cas, comme suggéré par @ Régis B., vous pouvez:

def mygen(lst, start): 
    for idx in range(len(lst)): 
     yield lst[(idx + start) % len(lst)] 
+1

Je serais enclin à utiliser quelque chose comme 'pour l'indice dans la gamme (len (mylist)): print maListe [(indice + start_index)% len (mylist)]', plutôt que d'une boucle 'while' . – jonrsharpe

+0

Oui, cela aurait été mieux :) Je suppose que je méritais la downvote ... – rll

+0

@rll Je doute qu'il a été downvoted à cause de cela ... Probablement à cause de 'i ++', que vous avez rapidement enlevé. – vaultah

0

Vous pouvez créer votre propre fonction iterator qui fait cela très haut la main (et efficace) , comme indiqué ci-dessous.

Il est important de noter que, tel qu'il est écrit, vous pouvez lui transmettre un index négatif, auquel la longueur de la liste est effective ajoutée, donc -2 signifierait l'avant-dernier élément d'une liste — qui est exactement comment Python lui-même gère normalement les index négatifs.

try: 
    xrange 
except NameError: # Python 3 
    xrange = range 

def starting_with(start_index, seq): 
    if start_index > 0: 
     start_index = start_index-len(seq) 
    for i in xrange(start_index, len(seq)+start_index): 
     yield seq[i] 

for value in starting_with(3, my_list): 
    ...