Réponses:
Les autres réponses ne fonctionnent que pour une séquence.
Pour tout itérable, pour ignorer le premier élément:
itercars = iter(cars)
next(itercars)
for car in itercars:
# do work
Si vous voulez sauter le dernier, vous pouvez faire:
itercars = iter(cars)
# add 'next(itercars)' here if you also want to skip the first
prev = next(itercars)
for car in itercars:
# do work on 'prev' not 'car'
# at end of loop:
prev = car
# now you can do whatever you want to do to the last one on 'prev'
Pour ignorer le premier élément en Python, vous pouvez simplement écrire
for car in cars[1:]:
# Do What Ever you want
ou pour sauter le dernier élément
for car in cars[:-1]:
# Do What Ever you want
Vous pouvez utiliser ce concept pour n'importe quelle séquence.
La meilleure façon d'ignorer le ou les premiers éléments est:
from itertools import islice
for car in islice(cars, 1, None):
# do something
islice dans ce cas est invoqué avec un point de départ de 1 et un point de fin de None, signifiant la fin de l'itérateur.
Pour pouvoir sauter des éléments à partir de la fin d'un itérable, vous devez connaître sa longueur (toujours possible pour une liste, mais pas nécessairement pour tout ce sur quoi vous pouvez itérer). par exemple, islice (cars, 1, len (cars) -1) ignorera les premier et dernier éléments de la liste des voitures.
isliceassez bien sauter un nombre arbitraire d'éléments au début et / ou à la fin de tout itérable , sans connaître la longueur ni stocker plus d'éléments en mémoire à la fois que ce qui est absolument nécessaire.
isliceest ce qui est passé à l' dequeitérateur, pas à l'itérateur entier, et c'est seulement la longueur du nombre d'éléments à sauter à la fin. Il ne stocke pas l'itérateur entier en mémoire.
Voici une fonction de générateur plus générale qui saute n'importe quel nombre d'éléments du début et de la fin d'un itérable:
def skip(iterable, at_start=0, at_end=0):
it = iter(iterable)
for x in itertools.islice(it, at_start):
pass
queue = collections.deque(itertools.islice(it, at_end))
for x in it:
queue.append(x)
yield queue.popleft()
Exemple d'utilisation:
>>> list(skip(range(10), at_start=2, at_end=2))
[2, 3, 4, 5, 6, 7]
at_end == 0.
skip(xrange(10000000), 1)utilisera at_end=0, donc le paramètre à deque()sera islice(it, 0), qui ne consommera que zéro élément de it. Cela ne prendra pas beaucoup de mémoire.
for item in do_not_use_list_as_a_name[1:-1]:
#...do whatever
listcomme nom de variable
listpeut être lié de nouveau. C'est pourquoi vous ne devriez pas , plutôt que ne pouvez pas , l'utiliser.
Exemple:
mylist=['one'.'two','three'.'four'.'five']
for i in mylist[1:]:
print(i)
Dans l'index python à partir de 0, nous pouvons utiliser l'opérateur de découpage pour effectuer des manipulations en itération.
for i in range(1,-1):
Basé sur la réponse de @SvenMarnach, mais un peu plus simple et sans utiliser deque
>>> def skip(iterable, at_start=0, at_end=0):
it = iter(iterable)
it = itertools.islice(it, at_start, None)
it, it1 = itertools.tee(it)
it1 = itertools.islice(it1, at_end, None)
return (next(it) for _ in it1)
>>> list(skip(range(10), at_start=2, at_end=2))
[2, 3, 4, 5, 6, 7]
>>> list(skip(range(10), at_start=2, at_end=5))
[2, 3, 4]
Notez également, sur la base de mon timeitrésultat, c'est légèrement plus rapide que la solution deque
>>> iterable=xrange(1000)
>>> stmt1="""
def skip(iterable, at_start=0, at_end=0):
it = iter(iterable)
it = itertools.islice(it, at_start, None)
it, it1 = itertools.tee(it)
it1 = itertools.islice(it1, at_end, None)
return (next(it) for _ in it1)
list(skip(iterable,2,2))
"""
>>> stmt2="""
def skip(iterable, at_start=0, at_end=0):
it = iter(iterable)
for x in itertools.islice(it, at_start):
pass
queue = collections.deque(itertools.islice(it, at_end))
for x in it:
queue.append(x)
yield queue.popleft()
list(skip(iterable,2,2))
"""
>>> timeit.timeit(stmt = stmt1, setup='from __main__ import iterable, skip, itertools', number = 10000)
2.0313770640908047
>>> timeit.timeit(stmt = stmt2, setup='from __main__ import iterable, skip, itertools, collections', number = 10000)
2.9903135454296716
tee(), vous créez toujours une liste entière en mémoire pour le générateur, non? (votre it1)
Eh bien, votre syntaxe n'est pas vraiment Python pour commencer.
Les itérations en Python sont sur le contenu des conteneurs (enfin, techniquement, c'est sur les itérateurs), avec une syntaxe for item in container. Dans ce cas, le conteneur est la carsliste, mais vous voulez ignorer le premier et le dernier éléments, ce qui signifie que cars[1:-1](les listes python sont de base zéro, les nombres négatifs comptent à partir de la fin et :tranchent la syntaxe.
Alors tu veux
for c in cars[1:-1]:
do something with c
Voici mon choix préféré. Il ne nécessite pas beaucoup d'ajout à la boucle et n'utilise que des outils intégrés.
Aller de:
for item in my_items:
do_something(item)
à:
for i, item in enumerate(my_items):
if i == 0:
continue
do_something(item)
Si carsc'est une séquence que vous pouvez simplement faire
for car in cars[1:-1]:
pass
Le more_itertoolsprojet s'étend itertools.islicepour gérer les indices négatifs.
Exemple
import more_itertools as mit
iterable = 'ABCDEFGH'
list(mit.islice_extended(iterable, 1, -1))
# Out: ['B', 'C', 'D', 'E', 'F', 'G']
Par conséquent, vous pouvez l'appliquer élégamment en tranches entre le premier et le dernier élément d'un itérable:
for car in mit.islice_extended(cars, 1, -1):
# do something
Je le fais comme ça, même si ça ressemble à un hack ça marche à chaque fois:
ls_of_things = ['apple', 'car', 'truck', 'bike', 'banana']
first = 0
last = len(ls_of_things)
for items in ls_of_things:
if first == 0
first = first + 1
pass
elif first == last - 1:
break
else:
do_stuff
first = first + 1
pass
for n, i in enumerate(cars): if n!= 0: do something to i. la logique est qu'il ajoute un «compteur» à chaque valeur que vous pouvez ensuite cibler par exemple avecif n == some_value. dans cet exemple, il ferait quelque chose pour chaque instance de i, sauf pour la première.