En utilisant « dans » pour correspondre à un attribut d'objets Python dans un tableau

voix
39

Je ne me souviens pas si je rêvais ou non, mais je crois me rappeler l'existence d'une fonction qui a permis à quelque chose comme,

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

Je l'ai regardé les documents, mais ce genre de chose ne tombe pas sous les en-têtes cotées évidentes

Créé 03/08/2008 à 14:19
source utilisateur
Dans d'autres langues...                            


8 réponses

voix
38

En utilisant une compréhension de liste construirait une liste temporaire, qui pourrait manger toute votre mémoire si la séquence recherchée est grande. Même si la séquence est pas grande, la construction de la liste itérer signifie sur l'ensemble de la séquence avant inpourrait commencer sa recherche.

La liste temporaire peut être éviter en utilisant une expression du générateur:

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

Maintenant, tant que obj.id == 12près du début bar, la recherche sera rapide, même si barest infiniment longue.

Comme suggéré @ Matt, il est une bonne idée d'utiliser hasattrsi l' un des objets barpeut manquer un idattribut:

foo = 12
foo in (obj.id for obj in bar if hasattr(obj, 'id'))
Créé 11/09/2008 à 23:42
source utilisateur

voix
10

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

result = [obj for obj in listOfObjs if hasattr(obj, 'attributeName')]
Créé 03/08/2008 à 16:59
source utilisateur

voix
8

vous pouvez toujours écrire vous-même:

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

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

J'adore python, il fait des trucs comme ça très simple et pas plus compliqué que neccessary, et l'utilisation des choses comme cela est extrêmement élégant.

Créé 27/08/2008 à 21:13
source utilisateur

voix
4

La fonction que vous pensez est probablement operator.attrgettter. Par exemple, pour obtenir une liste qui contient 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 façon de le faire est propre et efficace (c.-à ne pas itérer la liste complète inutilement):

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

Si vous souhaitez utiliser « dans » 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)

Créé 05/02/2011 à 09:10
source utilisateur

voix
4

Non, vous ne rêvez pas. Python a un joli excellent système de compréhension de la liste qui vous permet de manipuler des listes assez élégantes, et en fonction exactement ce que vous voulez accomplir, cela peut se faire de deux façons. Essentiellement, ce que vous faites est de dire « Pour l'article dans la liste si criteria.matches », et de ce que vous pouvez simplement parcourir les résultats ou vider les résultats dans une nouvelle liste.

Je vais au lit de bébé un exemple de Plongez au coeur de Python ici, car il est assez élégant et ils sont plus intelligents que moi. Ici , ils obtiennent une liste de fichiers dans un répertoire, puis filtrer la liste de 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 des expressions régulières, par votre exemple, pour quoi que ce soit où retourne votre expression à la véritable fin d'un match. Il existe d'autres options comme l'utilisation de la fonction filtre (), mais si je devais choisir, je partirais avec cela.

Eric Sipple

Créé 03/08/2008 à 15:30
source utilisateur

voix
3

Si vous envisagez de chercher quoi que ce soit de taille décente à distance, votre meilleur pari va être d'utiliser un dictionnaire ou d'un ensemble. Sinon, vous avez essentiellement à itérer tous les éléments du iterator jusqu'à ce que vous obtenez à celui que vous voulez.

Si ce n'est pas nécessairement les performances sensibles du code, la façon de la compréhension de la liste devrait fonctionner. Mais notez qu'il est assez inefficace, car il va sur tous les éléments du iterator puis remonte au-dessus à nouveau jusqu'à ce qu'il trouve ce qu'il veut.

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

Créé 27/08/2008 à 21:30
source utilisateur

voix
3

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

à-dire « bar » est une liste d'objets, qui ont tous l'attribut « id »

La façon fonctionnelle mythique:

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

La façon de la compréhension de la liste:

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

En rétrospective, la façon de la compréhension de la liste est assez de toute façon soignée.

Créé 03/08/2008 à 17:13
source utilisateur

voix
-1

Je pense:

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

Est - ce que vous pensez. Lorsque vous essayez de voir si une certaine clé existe dans un dictionnaire en python (version de python d'une table de hachage) , il y a deux façons de vérifier. La première est la has_key()méthode associée au dictionnaire et la seconde est l'exemple donné ci - dessus. Il renvoie une valeur booléenne.

Cela devrait répondre à votre question.

Et maintenant , un peu hors sujet pour attacher ce pour la compréhension de la liste réponse précédemment donnée (pour un peu plus de clarté). Liste compréhensions construire une liste à partir d' une base pour la boucle avec des modificateurs. À titre d'exemple (pour clarifier un peu), un moyen d'utiliser la in dictconstruction linguistique dans une compréhension de la liste :

Disons que vous avez deux dimensions dictionnaire fooet que vous voulez les dictionnaires de deuxième dimension qui contiennent la clé bar. Une façon de le faire serait relativement simple de façon à utiliser une compréhension de la liste avec un conditionnel comme suit:

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

Notez que la if bar in valuefin de la déclaration **, ceci est une clause de modification qui indique la compréhension de la liste pour ne conserver que les paires clé-valeur qui répondent à la condition. ** Dans ce cas , bazest un nouveau dictionnaire qui ne contient que les dictionnaires de foo qui contiennent bar ( un peu de chance , je ne manque rien dans cet exemple de code ... vous pouvez avoir à jeter un oeil à la documentation de compréhension de liste qui se trouve dans des tutoriels docs.python.org et à secnetix.de , les deux sites sont de bonnes références si vous avez des questions à l'avenir.).

Créé 03/08/2008 à 16:47
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more