une - self python




Utiliser 'in' pour faire correspondre un attribut d'objets Python dans un tableau (6)

Ce à quoi je pensais peut être réalisé en utilisant des compréhensions de liste, mais je pensais qu'il y avait une fonction qui a fait cela d'une manière légèrement plus nette.

ie 'bar' est une liste d'objets, tous ayant l'attribut 'id'

La manière fonctionnelle mythique:

foo = 12
foo in iter_attr(bar, 'id')

La façon de comprendre la liste:

foo = 12
foo in [obj.id for obj in bar]

Rétrospectivement, la méthode de compréhension de la liste est plutôt jolie.

Je ne me souviens pas si je rêvais ou non, mais je crois me rappeler qu'il y avait une fonction qui permettait quelque chose comme,

foo in iter_attr(array of python objects, attribute name)

J'ai regardé les docs mais ce genre de chose ne tombe pas sous les en-têtes listés


Cherchez-vous à obtenir une liste d'objets qui ont un certain attribut? Si oui, une compréhension de liste est la bonne façon de le faire.

result = [obj for obj in listOfObjs if hasattr(obj, 'attributeName')]

Si vous envisagez de chercher quelque chose de taille décente, votre meilleur pari sera d'utiliser un dictionnaire ou un ensemble. Sinon, vous devez essentiellement parcourir tous les éléments de l'itérateur jusqu'à ce que vous arriviez à celui que vous voulez.

Si ce n'est pas forcément un code sensible à la performance, la méthode de compréhension de la liste devrait fonctionner. Mais notez qu'il est assez inefficace car il va au-dessus de chaque élément de l'itérateur et revient ensuite dessus jusqu'à ce qu'il trouve ce qu'il veut.

Rappelez-vous, python a l'un des algorithmes de hachage les plus efficaces autour. Utilisez-le à votre avantage.


tu pourrais toujours en écrire un toi-même:

def iterattr(iterator, attributename):
    for obj in iterator:
        yield getattr(obj, attributename)

fonctionnera avec tout ce qui itère, que ce soit un tuple, une liste, ou autre.

J'adore les pythons, ça rend les trucs comme ça très simples et pas plus compliqués que nécessaire, et des trucs comme ça sont extrêmement élégants.


La fonction à laquelle vous pensez est probablement operator.attrgettter . Par exemple, pour obtenir une liste contenant la valeur de l'attribut "id" de chaque objet:

import operator
ids = map(operator.attrgetter("id"), bar)

Si vous voulez vérifier si la liste contient un objet avec un identifiant == 12, alors une manière propre et efficace (c'est-à-dire ne pas itérer inutilement toute la liste) est de le faire:

any(obj.id == 12 for obj in bar)

Si vous voulez utiliser 'in' avec attrgetter, tout en conservant l'itération paresseuse de la liste:

import operator,itertools
foo = 12
foo in itertools.imap(operator.attrgetter("id"), bar)


Non, tu ne rêvais pas. Python a un très bon système de compréhension de liste qui vous permet de manipuler les listes de manière assez élégante, et en fonction de ce que vous voulez accomplir, cela peut être fait de plusieurs façons. En substance, ce que vous faites est de dire "Pour l'élément dans la liste if criteria.matches", et à partir de cela, vous pouvez simplement parcourir les résultats ou vider les résultats dans une nouvelle liste.

Je vais donner un exemple de Dive Into Python ici, parce que c'est assez élégant et ils sont plus intelligents que moi. Ici, ils obtiennent une liste de fichiers dans un répertoire, puis filtrent la liste pour tous les fichiers qui correspondent à un critère d'expression régulière.

    files = os.listdir(path)                               
    test = re.compile("test\.py$", re.IGNORECASE)          
    files = [f for f in files if test.search(f)]

Vous pouvez le faire sans expressions régulières, pour votre exemple, pour tout ce que votre expression à la fin renvoie vrai pour une correspondance. Il y a d'autres options comme l'utilisation de la fonction filter (), mais si j'allais choisir, j'irais avec ça.

Eric Sipple





iteration