Je veux itérer sur tout ce qui se trouve dans une liste sauf les premiers éléments, par exemple :
for line in lines[2:]:
foo(line)
C'est concis, mais cela copie toute la liste, ce qui est inutile. Je pourrais le faire :
del lines[0:2]
for line in lines:
foo(line)
Mais cela modifie la liste, ce qui n'est pas toujours bon.
Je peux le faire :
for i in xrange(2, len(lines)):
line = lines[i]
foo(line)
Mais, c'est juste dégoûtant.
Le mieux serait peut-être ça :
for i,line in enumerate(lines):
if i < 2: continue
foo(line)
Mais ce n'est pas aussi évident que le tout premier exemple.
Alors : Quel est le moyen de le faire qui soit aussi évident que le premier exemple, mais qui ne copie pas la liste inutilement ?
11 votes
Je pense
for i in xrange(2, len(lines)):
est bien.0 votes
Juste par curiosité, quelle est la taille de la liste sur laquelle vous itérez ?
0 votes
@GregGuida : environ 300 lignes de texte.
6 votes
Je sais que cela ne répond pas à votre question, mais pour seulement 300 lignes de texte, je ne m'inquiéterais pas du tout de la copie. N'oubliez pas que seules les références sont copiées, et non les données de la chaîne elle-même...
1 votes
Personnellement, je préfère le quatrième exemple que vous avez donné. Il n'est pas moins efficace que le
islice
et, à mon avis, elle sera plus facile à lire et à comprendre pour toute autre personne regardant votre code.0 votes
@thesamet : Ah oui, j'avais oublié que les données elles-mêmes ne seraient pas copiées. C'est probablement vrai, mais je demandais plutôt le cas général.
1 votes
Je pense aussi
for i in xrange(2, len(lines))
est bien, et meilleur que n'importe lequel des choix ci-dessous. Pourquoi penses-tu que c'est "dégueulasse" ?2 votes
@BlueRaja-DannyPflughoeft : parce que la manière pythonique d'itérer est d'utiliser une
for-each
boucle :for x in stuff:
. vous ne faites pasfor i in xrange(len(stuff)): x=stuff[i]
alors pourquoi le faire si vous voulez simplement faire la même itération mais légèrement différente ?