J'ai une liste d'objets. Je veux trouver un (premier ou autre) objet dans cette liste dont l'attribut (ou le résultat de la méthode - peu importe) est égal à value
.
Quelle est la meilleure façon de le trouver?
Voici le cas de test:
class Test:
def __init__(self, value):
self.value = value
import random
value = 5
test_list = [Test(random.randint(0,100)) for x in range(1000)]
# that I would do in Pascal, I don't believe isn't anywhere near 'Pythonic'
for x in test_list:
if x.value == value:
print "i found it!"
break
Je pense qu'en utilisant des générateurs et reduce()
ne fera aucune différence, car il serait toujours en train de parcourir la liste.
ps .: L'équation de value
n'est qu'un exemple. Bien sûr, nous voulons obtenir un élément qui répond à toutes les conditions.
Réponses:
Cela obtient le premier élément de la liste qui correspond à la condition et retourne
None
si aucun élément ne correspond. C'est ma forme d'expression unique préférée.cependant,
La version naïve de rupture de boucle, est parfaitement Pythonic - elle est concise, claire et efficace. Pour l'adapter au comportement du monoplace:
Cela sera attribué
None
àx
si vous nebreak
sortez pas de la boucle.la source
... if getattr(x, x.fieldMemberName) == value
. Cela récupérera l'attributx
avec le nom stocké dansfieldMemberName
et le comparera àvalue
.else
clause est censée être sur lafor
boucle, pas laif
. (Modification rejetée).Puisqu'il n'a pas été mentionné juste pour l'achèvement. Le bon vieux filtre pour filtrer vos éléments à filtrer.
Programmation fonctionnelle ftw.
Je sais qu'en général, dans les listes de python, les compréhensions sont préférées ou du moins c'est ce que je lis, mais je ne vois pas le problème pour être honnête. Bien sûr, Python n'est pas un langage FP, mais Map / Reduce / Filter sont parfaitement lisibles et sont le plus standard des cas d'utilisation standard en programmation fonctionnelle.
Alors voilà. Connaissez votre programmation fonctionnelle.
liste des conditions de filtrage
Ce ne sera pas plus simple que ça:
la source
filter
retourne une liste qui n'est pas compatible avecnext
. 2 : il faut qu'il y ait une correspondance définitive, sinon vous obtiendrez uneStopIteration
exception.Un exemple simple : nous avons le tableau suivant
Maintenant, nous voulons trouver l'objet dans le tableau dont l'id est égal à 1
next
avec la compréhension de la listeLa sortie de toutes les méthodes ci-dessus est
{'id': 1, 'name': 'ronaldo'}
la source
Je viens de rencontrer un problème similaire et j'ai conçu une petite optimisation pour le cas où aucun objet de la liste ne répond à l'exigence (pour mon cas d'utilisation, cela a entraîné une amélioration des performances majeure):
Avec la liste test_list, je garde un ensemble supplémentaire test_value_set qui se compose des valeurs de la liste sur laquelle je dois filtrer. Ici, le reste de la solution d'agf devient très rapide.
la source
Vous pourriez faire quelque chose comme ça
C'est ce que j'utilise pour trouver les objets dans un long tableau d'objets.
la source
Vous pouvez également implémenter une comparaison riche via une
__eq__
méthode pour votreTest
classe et utiliser l'in
opérateur. Je ne sais pas si c'est la meilleure façon autonome, mais au cas où vous auriez besoin de comparer desTest
instances baséesvalue
ailleurs, cela pourrait être utile.la source
Pour le code ci-dessous, xGen est une expression de générateur anonome, yFilt est un objet filtre. Notez que pour xGen, le paramètre supplémentaire None est renvoyé plutôt que de lancer StopIteration lorsque la liste est épuisée.
Production:
la source