Bonjour,
J'aimerai savoir comment filtrer une liste à partir de 2 options:
soit c'est l'utilisateur qui saisi les paramètres à supprimer d'une liste ou soit à partir d'une liste de paramètres en entrée
Bonjour,
J'aimerai savoir comment filtrer une liste à partir de 2 options:
soit c'est l'utilisateur qui saisi les paramètres à supprimer d'une liste ou soit à partir d'une liste de paramètres en entrée
Ben, une fois que tu as ta liste d’éléments à exclure*:
Pour le reste, la question est un peu vague… Supposons simplement que ta liste d’éléments à exclure est au départ une string du type "el1, el2, el3", dans ce cas tu construis une vraie liste à partir ce ça grâce à split*:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 def list_filter(lst, flt): flt = set(flt) # Utiliser plutôt un set # On retourne simplement une nouvelle liste contenant tous # les éléments de lst qui ne se trouvent pas dans flt return [l for l in lst if l not in flt]
Voilà déjà quelques éléments de réponse, s’ils ne te suffisent pas, essaye de préciser un peu ta question…
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 usr_data = "el1, el2, el3" flt = usr_data.split(', ') # Va retourner ['el1', 'el2', 'el3']
oui mais j'ai oublié de préciser que les paramètres sont des mots clés....c'est à dire filtrer si ce mot clé est présent dans le mot
Gne*?
Je ne comprends pas ce que tu veux dire… Explique ou donne un exemple, s’il te plais…![]()
g par exemple la liste suivante:
liste = ("cellule_asd_0","cellule_bfm_1","cellule_tf_2","cellule_ask_3","cellule_ijk_4")
et j'ai envie de retirer la cellule avec _tf_ et _ijk_ par exemple
Dans ce cas, c’est très simple (quoi que plus verbeux) –*Python dispose d’une fonctionnalité de test de sous chaînes*:
[Edit] Pour le fun, il y a une formule en une seule ligne –*mais elle est peut-être moins facile à comprendre
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 def apply_mask(lst, mask): ret = [] for l in lst: valid = True for m in mask: if m in l: # Si cet motif est une sous-chaîne de lélément courant, on exclut ce dernier. valid = False break; if valid: ret.append(l) return ret lst = ("cellule_asd_0","cellule_bfm_1","cellule_tf_2","cellule_ask_3","cellule_ijk_4") mask = ("_tf_", "_ijk_") print(apply_mask(lst, mask)) # ['cellule_asd_0', 'cellule_bfm_1', 'cellule_ask_3']
Mais cette version est moins rapide, car elle compare systématiquement tous les éléments du mask à chaque élément de la liste, alors que le premier code s’arrête dès qu’il a trouvé une correspondance…
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 def apply_mask(lst, mask): return [l for l in lst if not filter(lambda m: m in l, mask)] lst = ("cellule_asd_0","cellule_bfm_1","cellule_tf_2","cellule_ask_3","cellule_ijk_4") mask = ("_tf_", "_ijk_") print(apply_mask(lst, mask)) # ['cellule_asd_0', 'cellule_bfm_1', 'cellule_ask_3']
et si je veux que se soit l'utilisateur qui rentre à la main ceux à filtrer je sais jamais si c'est raw_input() ou input() qu'il faut mettre
En python2, c’est raw_input() (car input() appelle implicitement eval() sur l’entrée utilisateur…).
En python3, c’est input().
@mont29
L'opérateur - est surchargé dans les set pour implémenter le complémentaire.
Code python : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 def list_filter(lst, flt): flt = set(flt) # Utiliser plutôt un set # On retourne simplement une nouvelle liste contenant tous # les éléments de lst qui ne se trouvent pas dans flt return lst-flt
Ce qu'on trouve est plus important que ce qu'on cherche.
Maths de base pour les nuls (et les autres...)
@Zavonen*: certes, mais uniquement entre set, ça ne marche pas avec une liste (hélas…)*:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 >>> lst = [1,2,3,4,5,6,5,4,3,2,1] >>> msk = set((1,3,4)) >>> lst - msk Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unsupported operand type(s) for -: 'list' and 'set'
voici deux solution 'inplace' (ie agit directement sur la liste passée en argument au lieu d'en retourner une nouvelle):
- un façon apparemment adaptée à ton problème:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 >>> def inplace_filter2(lst, *forbiden): for i in xrange(len(lst)-1,-1,-1): key = lst[i] if any(forbid in key for forbid in forbiden): del lst[i] >>> l=['foo','foo_f_t_','fooooo','fooooo_f_t_'] >>> inplace_filter2(l,'_f_','_t_') >>> l ['foo', 'fooooo']- une autre plus générale:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 >>> def inplace_filter(lst, func): #func est une fonction devant retourner True pour effacemen ou False pour laisser for i in xrange(len(lst)-1,-1,-1): if func(lst[i]): del lst[i] >>> l=['foo','foo_f_t_','fooooo','fooooo_f_t_'] >>> inplace_filter(l,lambda x: '_f_t_' in x) >>> l ['foo', 'fooooo']
@Zavonen*: certes, mais uniquement entre set, ça ne marche pas avec une liste (hélas…)*:
C'est logique à cause des occurrences multiples.
Pour deux listes L1 et L2 le 'concept' L1-L2 n'est pas clair, pour des ensembles il n'y a aucune ambiguïté.
Ce qu'on trouve est plus important que ce qu'on cherche.
Maths de base pour les nuls (et les autres...)
Entre deux listes, je suis d’accord, mais je pensais au cas qui nous occupe ici, «*list - set*» –*là, la signification me semble des plus claire (enlever de la liste tous les éléments qui se trouvent dans l’ensemble), mais ça n’est pas implémenté, dommage…
Partager