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

Translate

Je ne me souviens pas si je rêvais ou non mais je me souviens 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 documents mais ce genre de chose ne relève d'aucun en-tête évident

This question and all comments follow the "Attribution Required."

Toutes les réponses

Translate

L'utilisation d'une compréhension de liste créerait une liste temporaire, qui pourrait manger toute votre mémoire si la séquence recherchée est volumineuse. Même si la séquence n'est pas volumineuse, la construction de la liste signifie une itération sur l'ensemble de la séquence avantinpourrait commencer sa recherche.

La liste temporaire peut être évitée en utilisant une expression de générateur:

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

Maintenant, tant queobj.id == 12près du début debar, la recherche sera rapide, même sibarest infiniment long.

Comme @Matt l'a suggéré, c'est une bonne idée d'utiliserhasattrsi l'un des objets dansbarpeut manquer unidattribut:

foo = 12
foo in (obj.id for obj in bar if hasattr(obj, 'id'))
La source
Translate

Cherchez-vous à obtenir une liste d'objets qui ont un certain attribut? Si oui, uncompréhension de listeest la bonne façon de procéder.

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

vous pouvez toujours en écrire un vous-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 le python, cela rend des trucs comme ça très simples et pas plus compliqués que nécessaires, et en utilisation, des trucs comme celui-ci sont extrêmement élégants.

La source
Translate

Non, vous ne rêviez pas. Python a un excellent système de compréhension de liste qui vous permet de manipuler les listes de manière assez élégante, et en fonction exactement 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 de la liste si les critères. Correspond", et à partir de là, vous pouvez simplement parcourir les résultats ou les vider dans une nouvelle liste.

Je vais donner un exemple dePlongez dans Pythonici, 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 true pour une correspondance. Il existe d'autres options comme l'utilisation de la fonction filter (), mais si je devais choisir, j'irais avec ça.

Eric Sipple

La source
Translate

La fonction à laquelle vous pensez est probablementoperator.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 id == 12, alors une manière soignée et efficace (c'est-à-dire ne pas itérer inutilement toute la liste) est:

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

Si vous souhaitez 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)

La source
Translate

Ce à quoi je pensais peut être réalisé en utilisant la compréhension de liste, mais je pensais qu'il y avait une fonction qui faisait cela d'une manière légèrement plus soignée.

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

La manière fonctionnelle mythique:

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

La manière de comprendre la liste:

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

Rétrospectivement, la manière de comprendre la liste est de toute façon assez soignée.

La source
Translate

Si vous envisagez de rechercher quelque chose de taille décente à distance, le mieux sera d'utiliser un dictionnaire ou un ensemble. Sinon, vous devez essentiellement parcourir chaque élément de l'itérateur jusqu'à ce que vous arriviez à celui que vous souhaitez.

Si ce n'est pas nécessairement un code sensible aux performances, la méthode de compréhension de liste devrait fonctionner. Mais notez qu'il est assez inefficace car il passe en revue chaque élément de l'itérateur, puis revient en arrière jusqu'à ce qu'il trouve ce qu'il veut.

N'oubliez pas que python possède l'un des algorithmes de hachage les plus efficaces. Utilisez-le à votre avantage.

La source
Translate

Je pense:

#!/bin/python
bar in dict(Foo)

Est ce à quoi vous pensez. Lorsque vous essayez de voir si une certaine clé existe dans un dictionnaire en python (version python d'une table de hachage), il existe deux façons de vérifier. Le premier est lehas_key()méthode attachée au dictionnaire et la seconde est l'exemple donné ci-dessus. Il renverra une valeur booléenne.

Cela devrait répondre à votre question.

Et maintenant un peu hors sujet pour lier cela à lacompréhension de listeréponse donnée précédemment (pour un peu plus de clarté).Compréhensions de la listeconstruire une liste à partir d'une basepour boucleavec des modificateurs. A titre d'exemple (pour clarifier légèrement), une façon d'utiliser lein dictconstruction de langage dans uncompréhension de liste:

Disons que vous avez un dictionnaire à deux dimensionsfooet vous ne voulez que les dictionnaires de deuxième dimension qui contiennent la clébar. Un moyen relativement simple de le faire serait d'utiliser uncompréhension de listeavec un conditionnel comme suit:

#!/bin/python
baz = dict([(key, value) for key, value in foo if bar in value])

Noter laif bar in valueà la fin de l'instruction **, il s'agit d'une clause de modification qui indique aucompréhension de listepour ne conserver que les paires clé-valeur qui remplissent la condition. ** Dans ce casbazest un nouveau dictionnaire qui ne contient que les dictionnaires de foo qui contiennent bar (J'espère que je n'ai rien manqué dans cet exemple de code ... vous devrez peut-être jeter un œil à la documentation de compréhension de liste trouvée dansdidacticiels docs.python.orget àsecnetix.de, les deux sites sont de bonnes références si vous avez des questions à l'avenir.).

La source