Je débute en Python, je cherche à supprimer des chaînes
(correspondant à un certain critère) dans une liste, et je ne suis pas
trop satisfait du code auquel je suis parvenu.
Exemple simple:
l=["total 3", "taratata titi toto"]
for line in l:
sl = line.split()
if len(sl) == 2 and sl[0] == "total" :
l.remove(line)
Auriez-vous une piste vers quelque chose de plus élégant ?
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Bruno Desthuilliers
Bonjour,
Je débute en Python, je cherche à supprimer des chaînes (correspondant à un certain critère) dans une liste, et je ne suis pas trop satisfait du code auquel je suis parvenu. Exemple simple: l=["total 3", "taratata titi toto"] for line in l: sl = line.split() if len(sl) == 2 and sl[0] == "total" : l.remove(line)
Modifier la liste sur laquelle on itère est généralement assez risqué:
l = range(10) for n, i in enumerate(l): ... print n, i
... if i % 2 : del l[i] ... 0 0 1 1 2 3 3 5 4 6 5 8 6 9 Traceback (most recent call last): File "<stdin>", line 3, in <module> IndexError: list assignment index out of range
Auriez-vous une piste vers quelque chose de plus élégant ?
Tu ne nous dit pas grand chose sur le contexte...
A tu vraiment besoin de modifier la liste "en place", ou la création d'une nouvelle liste est-elle ok ?
La condition est-elle toujours la même est-elle appelée à changer ?
En tout état de cause, les solutions "canoniques" se basent généralement sur la création d'une nouvelle liste "filtrée" (pour éviter les effets de bords indésirables constatés ci dessus), en utilisant soit la fonction filter soit une liste en intention.
# definition d'un prédicat pour déterminer si on doit garder la ligne # ou la supprimer:
def keep(line): parts = line.split() if len(parts) == 2 and parts[0] == "total": return False return True
source = ["total 3", "taratata titi toto"]
# par filtrage: dest = filter(keep, source)
# avec une liste en intention: dest = [line for line in source if keep(line)]
Après, on peut varier les approches pour le prédicat, par exemple avec une regexp:
import re test_exp = re.compile(r'^total d+$')
dest = filter(lambda line: test_exp.match(line), source)
etc...
Si la liste est partagée et que tu a vraiment besoin de modifier l'original, tu peux le faire ainsi:
dest = [line for line in source if keep(line)] source[:] = dest
HTH
Bonjour,
Je débute en Python, je cherche à supprimer des chaînes (correspondant
à un certain critère) dans une liste, et je ne suis pas trop satisfait
du code auquel je suis parvenu.
Exemple simple:
l=["total 3", "taratata titi toto"]
for line in l:
sl = line.split()
if len(sl) == 2 and sl[0] == "total" :
l.remove(line)
Modifier la liste sur laquelle on itère est généralement assez risqué:
l = range(10)
for n, i in enumerate(l):
... print n, i
... if i % 2 : del l[i]
...
0 0
1 1
2 3
3 5
4 6
5 8
6 9
Traceback (most recent call last):
File "<stdin>", line 3, in <module>
IndexError: list assignment index out of range
Auriez-vous une piste vers quelque chose de plus élégant ?
Tu ne nous dit pas grand chose sur le contexte...
A tu vraiment besoin de modifier la liste "en place", ou la création
d'une nouvelle liste est-elle ok ?
La condition est-elle toujours la même est-elle appelée à changer ?
En tout état de cause, les solutions "canoniques" se basent généralement
sur la création d'une nouvelle liste "filtrée" (pour éviter les effets
de bords indésirables constatés ci dessus), en utilisant soit la
fonction filter soit une liste en intention.
# definition d'un prédicat pour déterminer si on doit garder la ligne
# ou la supprimer:
def keep(line):
parts = line.split()
if len(parts) == 2 and parts[0] == "total":
return False
return True
source = ["total 3", "taratata titi toto"]
# par filtrage:
dest = filter(keep, source)
# avec une liste en intention:
dest = [line for line in source if keep(line)]
Après, on peut varier les approches pour le prédicat, par exemple avec
une regexp:
import re
test_exp = re.compile(r'^total d+$')
dest = filter(lambda line: test_exp.match(line), source)
etc...
Si la liste est partagée et que tu a vraiment besoin de modifier
l'original, tu peux le faire ainsi:
dest = [line for line in source if keep(line)]
source[:] = dest
Je débute en Python, je cherche à supprimer des chaînes (correspondant à un certain critère) dans une liste, et je ne suis pas trop satisfait du code auquel je suis parvenu. Exemple simple: l=["total 3", "taratata titi toto"] for line in l: sl = line.split() if len(sl) == 2 and sl[0] == "total" : l.remove(line)
Modifier la liste sur laquelle on itère est généralement assez risqué:
l = range(10) for n, i in enumerate(l): ... print n, i
... if i % 2 : del l[i] ... 0 0 1 1 2 3 3 5 4 6 5 8 6 9 Traceback (most recent call last): File "<stdin>", line 3, in <module> IndexError: list assignment index out of range
Auriez-vous une piste vers quelque chose de plus élégant ?
Tu ne nous dit pas grand chose sur le contexte...
A tu vraiment besoin de modifier la liste "en place", ou la création d'une nouvelle liste est-elle ok ?
La condition est-elle toujours la même est-elle appelée à changer ?
En tout état de cause, les solutions "canoniques" se basent généralement sur la création d'une nouvelle liste "filtrée" (pour éviter les effets de bords indésirables constatés ci dessus), en utilisant soit la fonction filter soit une liste en intention.
# definition d'un prédicat pour déterminer si on doit garder la ligne # ou la supprimer:
def keep(line): parts = line.split() if len(parts) == 2 and parts[0] == "total": return False return True
source = ["total 3", "taratata titi toto"]
# par filtrage: dest = filter(keep, source)
# avec une liste en intention: dest = [line for line in source if keep(line)]
Après, on peut varier les approches pour le prédicat, par exemple avec une regexp:
import re test_exp = re.compile(r'^total d+$')
dest = filter(lambda line: test_exp.match(line), source)
etc...
Si la liste est partagée et que tu a vraiment besoin de modifier l'original, tu peux le faire ainsi:
dest = [line for line in source if keep(line)] source[:] = dest
HTH
Pierre Maurette
Bonjour,
Je débute en Python, je cherche à supprimer des chaînes (correspondant à un certain critère) dans une liste, et je ne suis pas trop satisfait du code auquel je suis parvenu. Exemple simple: l=["total 3", "taratata titi toto"] for line in l: sl = line.split() if len(sl) == 2 and sl[0] == "total" : l.remove(line)
Auriez-vous une piste vers quelque chose de plus élégant ?
Elégant, je ne sais pas. Quelques propositions:
l=["total 3", "taratata titi toto"]
[l.remove(s) for s in l if s.split()[0] == 'total' and len(s.split()) == 2] print l
l=["total 3", "taratata titi toto"]
print [s for s in l if s.split()[0] != 'total' or len(s.split()) != 2]
print filter(lambda s:s.split()[0] != 'total' or len(s.split()) != 2, l)
Dans la première série, on appelle deux fois split() par itération. Enfin, on l'appelle deux fois si le premier appel ne permet pas de conclure (évaluation économique des booléens), il suffit peut-être de choisir l'ordre selon le contexte.
-- Pierre Maurette
Bonjour,
Je débute en Python, je cherche à supprimer des chaînes (correspondant à
un certain critère) dans une liste, et je ne suis pas trop satisfait du code
auquel je suis parvenu.
Exemple simple:
l=["total 3", "taratata titi toto"]
for line in l:
sl = line.split()
if len(sl) == 2 and sl[0] == "total" :
l.remove(line)
Auriez-vous une piste vers quelque chose de plus élégant ?
Elégant, je ne sais pas. Quelques propositions:
l=["total 3", "taratata titi toto"]
[l.remove(s) for s in l if s.split()[0] == 'total' and len(s.split())
== 2]
print l
l=["total 3", "taratata titi toto"]
print [s for s in l if s.split()[0] != 'total' or len(s.split()) != 2]
print filter(lambda s:s.split()[0] != 'total' or len(s.split()) != 2,
l)
Dans la première série, on appelle deux fois split() par itération.
Enfin, on l'appelle deux fois si le premier appel ne permet pas de
conclure (évaluation économique des booléens), il suffit peut-être de
choisir l'ordre selon le contexte.
Je débute en Python, je cherche à supprimer des chaînes (correspondant à un certain critère) dans une liste, et je ne suis pas trop satisfait du code auquel je suis parvenu. Exemple simple: l=["total 3", "taratata titi toto"] for line in l: sl = line.split() if len(sl) == 2 and sl[0] == "total" : l.remove(line)
Auriez-vous une piste vers quelque chose de plus élégant ?
Elégant, je ne sais pas. Quelques propositions:
l=["total 3", "taratata titi toto"]
[l.remove(s) for s in l if s.split()[0] == 'total' and len(s.split()) == 2] print l
l=["total 3", "taratata titi toto"]
print [s for s in l if s.split()[0] != 'total' or len(s.split()) != 2]
print filter(lambda s:s.split()[0] != 'total' or len(s.split()) != 2, l)
Dans la première série, on appelle deux fois split() par itération. Enfin, on l'appelle deux fois si le premier appel ne permet pas de conclure (évaluation économique des booléens), il suffit peut-être de choisir l'ordre selon le contexte.
-- Pierre Maurette
Bruno Piguet
Modifier la liste sur laquelle on itère est généralement assez risqué:
C'était bien ça que je voulais éviter. Même sans l'exemple fourni gentiment, je sentais bien le danger.
En tout état de cause, les solutions "canoniques" se basent généralement sur la création d'une nouvelle liste "filtrée" (pour éviter les effets de bords indésirables constatés ci dessus), en utilisant soit la fonction filter soit une liste en intention.
Bon sang mais c'est bien sûr ! filter() ! c'est dans toutes les docs !
En fait, j'étais parti à la recherche d'un truc du genre dest = source [where keep(source)]) C'est une construction qui existe dans d'autre langages... et qui m'avait fait perdre de vue les choses simples et directes.
Merci.
Bruno.
Modifier la liste sur laquelle on itère est généralement assez risqué:
C'était bien ça que je voulais éviter. Même sans l'exemple fourni
gentiment, je sentais bien le danger.
En tout état de cause, les solutions "canoniques" se basent généralement
sur la création d'une nouvelle liste "filtrée" (pour éviter les effets
de bords indésirables constatés ci dessus), en utilisant soit la
fonction filter soit une liste en intention.
Bon sang mais c'est bien sûr ! filter() ! c'est dans toutes les docs !
En fait, j'étais parti à la recherche d'un truc du genre
dest = source [where keep(source)])
C'est une construction qui existe dans d'autre langages... et qui
m'avait fait perdre de vue les choses simples et directes.
Modifier la liste sur laquelle on itère est généralement assez risqué:
C'était bien ça que je voulais éviter. Même sans l'exemple fourni gentiment, je sentais bien le danger.
En tout état de cause, les solutions "canoniques" se basent généralement sur la création d'une nouvelle liste "filtrée" (pour éviter les effets de bords indésirables constatés ci dessus), en utilisant soit la fonction filter soit une liste en intention.
Bon sang mais c'est bien sûr ! filter() ! c'est dans toutes les docs !
En fait, j'étais parti à la recherche d'un truc du genre dest = source [where keep(source)]) C'est une construction qui existe dans d'autre langages... et qui m'avait fait perdre de vue les choses simples et directes.
Merci.
Bruno.
Bruno Desthuilliers
Modifier la liste sur laquelle on itère est généralement assez risqué:
C'était bien ça que je voulais éviter. Même sans l'exemple fourni gentiment, je sentais bien le danger.
En tout état de cause, les solutions "canoniques" se basent généralement sur la création d'une nouvelle liste "filtrée" (pour éviter les effets de bords indésirables constatés ci dessus), en utilisant soit la fonction filter soit une liste en intention.
Bon sang mais c'est bien sûr ! filter() ! c'est dans toutes les docs !
En fait, j'étais parti à la recherche d'un truc du genre dest = source [where keep(source)])
C'est une construction qui existe dans d'autre langages... et qui m'avait fait perdre de vue les choses simples et directes.
En Python, c'est:
dest = [item for item in source if keep(item)]
(construction essentiellement pompée à Haskell...)
Modifier la liste sur laquelle on itère est généralement assez risqué:
C'était bien ça que je voulais éviter. Même sans l'exemple fourni
gentiment, je sentais bien le danger.
En tout état de cause, les solutions "canoniques" se basent
généralement sur la création d'une nouvelle liste "filtrée" (pour
éviter les effets de bords indésirables constatés ci dessus), en
utilisant soit la fonction filter soit une liste en intention.
Bon sang mais c'est bien sûr ! filter() ! c'est dans toutes les docs !
En fait, j'étais parti à la recherche d'un truc du genre
dest = source [where keep(source)])
C'est une construction qui existe dans d'autre langages... et qui
m'avait fait perdre de vue les choses simples et directes.
En Python, c'est:
dest = [item for item in source if keep(item)]
(construction essentiellement pompée à Haskell...)
Modifier la liste sur laquelle on itère est généralement assez risqué:
C'était bien ça que je voulais éviter. Même sans l'exemple fourni gentiment, je sentais bien le danger.
En tout état de cause, les solutions "canoniques" se basent généralement sur la création d'une nouvelle liste "filtrée" (pour éviter les effets de bords indésirables constatés ci dessus), en utilisant soit la fonction filter soit une liste en intention.
Bon sang mais c'est bien sûr ! filter() ! c'est dans toutes les docs !
En fait, j'étais parti à la recherche d'un truc du genre dest = source [where keep(source)])
C'est une construction qui existe dans d'autre langages... et qui m'avait fait perdre de vue les choses simples et directes.
En Python, c'est:
dest = [item for item in source if keep(item)]
(construction essentiellement pompée à Haskell...)