filtrer les éléments dans un dictionnaire python où les clés contiennent une chaîne spécifique
je suis un codeur C développant quelque chose en python. Je sais faire ce qui suit en C (et donc dans la logique de type C appliquée à python), mais je me demande Quelle est la façon de faire "Python".
j'ai un dictionnaire d, et je voudrais opérer sur un sous-ensemble des éléments, seulement ceux qui la clé de who's (chaîne) contient un substrat spécifique.
c'est à dire le C logique serait:
for key in d:
if filter_string in key:
# do something
else
# do nothing, continue
j'imagine que la version python serait quelque chose comme
filtered_dict = crazy_python_syntax(d, substring)
for key,value in filtered_dict.iteritems():
# do something
j'ai trouvé beaucoup de messages sur ce site concernant les dictionnaires de filtrage, mais je n'ai pas pu en trouver un qui impliquait exactement ceci.
Mon dictionnaire n'est pas imbriqué et j'utilise python 2.7
5 réponses
Que Diriez-vous d'un dict compréhension :
filtered_dict = {k:v for k,v in d.iteritems() if filter_string in k}
celui que vous voyez, il devrait être explicite, comme il se lit comme l'anglais assez bien.
cette syntaxe nécessite Python 2.7 ou plus.
en Python 3, Il n'y a que dict.items()
, pas iteritems()
donc vous utiliseriez:
filtered_dict = {k:v for (k,v) in d.items() if filter_string in k}
choisissez ce qui est le plus lisible et facile à entretenir. Juste parce que vous pouvez l'écrire en une seule ligne ne signifie pas que vous devriez. Votre solution existante est proche de ce que j'utiliserais si ce n'était que j'utiliserais des itéritems pour sauter la recherche de valeur, et je déteste les ifs imbriqués si je peux les éviter:
for key, val in d.iteritems():
if filter_string not in key:
continue
# do something
cependant si vous voulez vraiment quelque chose pour vous laisser itérer à travers un DCT filtré alors je ne ferais pas le processus en deux étapes de la construction du filtre dict puis itération à travers elle, mais à la place utiliser un générateur, parce que ce qui est plus pythonique (et génial) qu'un générateur?
nous créons D'abord notre générateur, et la bonne conception nous dicte de le rendre assez abstrait pour être réutilisable:
# The implementation of my generator may look vaguely familiar, no?
def filter_dict(d, filter_string):
for key, val in d.iteritems():
if filter_string not in key:
continue
yield key, val
et ensuite nous pouvons utiliser le générateur pour résoudre votre problème gentiment et proprement avec un code simple et compréhensible:
for key, val in filter_dict(d, some_string):
# do something
en bref: les générateurs sont géniaux.
input = {"A":"a", "B":"b", "C":"c"}
output = {k:v for (k,v) in input.items() if key_satifies_condition(k)}
Jonathon vous a donné une approche en utilisant des interprétations dict dans sa réponse . Voici une approche qui traite de votre faire quelque chose partie.
si vous voulez faire quelque chose avec les valeurs du dictionnaire, vous n'avez pas besoin d'une compréhension de dictionnaire du tout:
j'utilise iteritems(
) puisque vous avez étiqueté votre question avec python-2.7
results = map(some_function, [(k,v) for k,v in a_dict.iteritems() if 'foo' in k])
Maintenant, le résultat sera une liste avec some_function
appliqué à chaque paire clé/valeur du dictionnaire, qui a foo
dans sa clé.
si vous voulez juste traiter avec les valeurs et ignorer les clés, il suffit de changer la compréhension de la liste:
results = map(some_function, [v for k,v in a_dict.iteritems() if 'foo' in k])
some_function
peut être n'importe quel appelable, de sorte qu'un lambda fonctionnerait ainsi:
results = map(lambda x: x*2, [v for k,v in a_dict.iteritems() if 'foo' in k])
la liste intérieure n'est pas requis, car vous pouvez passer un expression génératrice pour map ainsi:
>>> map(lambda a: a[0]*a[1], ((k,v) for k,v in {2:2, 3:2}.iteritems() if k == 2))
[4]
vous pouvez utiliser la fonction pour filtrer les dictionnaires, les listes, etc. basés sur des conditions spécifiques.
filtered_dict = dict(filter(lambda item: filter_str in item[0], d.items()))
L'avantage est que vous pouvez l'utiliser pour différentes structures de données.