una - sotto classe python




Usare 'in' per abbinare un attributo di oggetti Python in una matrice (6)

Non ricordo se stavo sognando o no, ma mi sembra di ricordare che esisteva una funzione che permetteva qualcosa del genere,

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

Ho esaminato i documenti, ma questo genere di cose non rientra in alcun ovvio titolo elencato


Credo:

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

È quello che stai pensando. Quando si prova a vedere se esiste una certa chiave all'interno di un dizionario in python (la versione di Python di una tabella hash) ci sono due modi per controllare. Il primo è il metodo has_key() allegato al dizionario e il secondo è l'esempio sopra riportato. Restituirà un valore booleano.

Questo dovrebbe rispondere alla tua domanda.

E ora un po 'fuori tema per legare questo alla risposta di comprensione della lista precedentemente fornita (per un po' più di chiarezza). La lista delle comprensioni costruisce una lista da un ciclo di base con modificatori. Ad esempio (per chiarire leggermente), un modo per usare il costrutto del linguaggio in dict in una lista di comprensione :

Di 'che hai un dizionario bidimensionale foo e vuoi solo i dizionari di seconda dimensione che contengono la bar tasti. Un modo relativamente semplice per farlo sarebbe usare una comprensione di lista con un condizionale come segue:

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

Notare la if bar in value alla fine dell'istruzione **, questa è una clausola di modifica che dice alla comprensione dell'elenco di mantenere solo quelle coppie chiave-valore che soddisfano il condizionale. ** In questo caso baz è un nuovo dizionario che contiene solo i dizionari di foo che contengono la barra (spero di non aver perso nulla in quell'esempio di codice ... potresti dover dare un'occhiata alla documentazione di comprensione degli elenchi che si trova nei tutorial di docs.python.org e in secnetix.de , entrambi i siti sono buoni riferimenti se hai domande in futuro.).


Quello a cui stavo pensando si può ottenere usando le list comprehensions, ma ho pensato che esistesse una funzione che lo faceva in un modo leggermente più ordinato.

per esempio 'bar' è una lista di oggetti, ognuno dei quali ha l'attributo 'id'

Il modo funzionale mitico:

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

Il modo di comprendere la lista:

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

In retrospettiva, la modalità di comprensione delle liste è comunque abbastanza carina.


Se stai pianificando di cercare qualcosa di dimensioni decenti, la soluzione migliore è usare un dizionario o un set. Altrimenti, devi fondamentalmente scorrere tutti gli elementi dell'iteratore fino a raggiungere quello desiderato.

Se questo non è necessariamente un codice sensibile alle prestazioni, allora il modo di comprendere le liste dovrebbe funzionare. Notate che è piuttosto inefficiente perché passa su ogni elemento dell'iteratore e poi torna su INDIETRO fino a quando non trova ciò che vuole.

Ricorda, Python ha uno degli algoritmi di hashing più efficienti in circolazione. Usalo a tuo vantaggio.


potresti sempre scriverne uno tu stesso:

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

funzionerà con qualsiasi cosa iteri, che si tratti di una tupla, di una lista o di qualsiasi altra cosa.

Adoro Python, rende le cose come queste molto semplici e non più di una seccatura del necessario, e in uso roba del genere è estremamente elegante.


La funzione a cui stai pensando è probabilmente operator.attrgettter . Ad esempio, per ottenere un elenco contenente il valore dell'attributo "id" di ciascun oggetto:

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

Se si desidera verificare se l'elenco contiene un oggetto con un id == 12, allora un modo accurato ed efficiente (cioè non iterare l'intera lista inutilmente) modo di farlo è:

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

Se si desidera utilizzare 'in' con attrgetter, pur mantenendo l'iterazione pigra della lista:

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


No, non stavi sognando. Python ha un sistema di comprensione delle liste piuttosto eccellente che ti permette di manipolare le liste in modo elegante e, a seconda di cosa esattamente vuoi ottenere, questo può essere fatto in due modi. In sostanza, quello che stai facendo è dire "Per elemento in lista se criteria.matches", e da quello puoi semplicemente scorrere i risultati o scaricare i risultati in un nuovo elenco.

Prenderò qui un esempio di Dive Into Python , perché è molto elegante e sono più intelligenti di me. Qui ricevono un elenco di file in una directory, quindi filtrano l'elenco per tutti i file che corrispondono a un criterio di espressione regolare.

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

Puoi farlo senza espressioni regolari, per il tuo esempio, per qualsiasi cosa in cui la tua espressione alla fine ritorna vera per una corrispondenza. Ci sono altre opzioni come usare la funzione filter (), ma se dovessi scegliere, andrei con questo.

Eric Sipple







iteration