Korzystanie z „w”, aby dopasować atrybut obiektów Pythona w tablicy

głosy
39

Nie pamiętam, czy śnię czy nie, ale wydaje mi się, że pamiętam jest funkcją co pozwoliło coś podobnego,

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

Szukałem na docs ale tego typu rzeczy nie podlega żadnej oczywistych nagłówków giełdowych

Utwórz 03/08/2008 o 14:19
źródło użytkownik
W innych językach...                            


8 odpowiedzi

głosy
38

Korzystanie z listy ze zrozumieniem by zbudować tymczasową listę, która może zjeść całą swoją pamięć, jeśli sekwencja poszukiwany jest duża. Nawet jeśli sekwencja nie jest duża, budowanie listy oznacza Iterowanie nad całością sekwencji przed inmógł rozpocząć swoje poszukiwania.

Wykaz tymczasowy może być unikanie za pomocą wyrażenia generatora:

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

Teraz, tak długo, jak obj.id == 12blisko początku bar, wyszukiwanie będzie szybkie, nawet jeśli barjest nieskończenie długa.

Jak sugeruje @Matt, że to dobry pomysł, aby użyć hasattr, jeśli któryś z obiektów barmoże być brakuje idatrybutu:

foo = 12
foo in (obj.id for obj in bar if hasattr(obj, 'id'))
Odpowiedział 11/09/2008 o 23:42
źródło użytkownik

głosy
10

Czy chcesz uzyskać listę obiektów, które mają pewną cechę? Jeśli tak, to lista rozumienie jest właściwym sposobem, aby to zrobić.

result = [obj for obj in listOfObjs if hasattr(obj, 'attributeName')]
Odpowiedział 03/08/2008 o 16:59
źródło użytkownik

głosy
8

zawsze można napisać samemu:

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

będzie działać z niczego, iteracje, czy to krotka lista, czy cokolwiek innego.

Kocham pytona, to robi takie rzeczy bardzo prosta i nie więcej kłopotów niż neccessary i używane rzeczy, jak to jest niezwykle elegancki.

Odpowiedział 27/08/2008 o 21:13
źródło użytkownik

głosy
4

Funkcja myślisz chyba operator.attrgettter. Na przykład, aby uzyskać listę zawierającą wartości atrybutu „id” każdego obiektu:

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

Jeśli chcesz sprawdzić, czy lista zawiera obiekt z krytym == id 12, to schludny i efektywny (tj nie iteracyjne całą listę niepotrzebnie) sposobem na to jest:

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

Jeśli chcesz korzystać z „w” z attrgetter, zachowując przy leniwy iteracji listy:

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

Odpowiedział 05/02/2011 o 09:10
źródło użytkownik

głosy
4

Nie, nie śni. Python ma dość doskonały system listowych, który pozwala manipulować list dość elegancko, w zależności od tego, co dokładnie chcesz osiągnąć, można to zrobić na kilka sposobów. W istocie, co robisz mówi „Dla pozycji na liście, jeśli criteria.matches”, i od tego można po prostu iterację wyników lub zrzucić wyniki do nowej listy.

Idę szopka przykład z Dive Into Python tutaj, ponieważ jest to bardzo elegancki i są mądrzejsi niż ja. Tutaj są one coraz listę plików w katalogu, a następnie filtrując listę wszystkich plików pasujących do regularnych kryteria ekspresyjne.

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

Można to zrobić bez wyrażeń regularnych, dla przykładu, na cokolwiek, gdzie ekspresja pod koniec Zwraca true na mecz. Są jeszcze inne opcje, takie jak przy użyciu funkcji filter (), ale jeśli ja jechaliśmy do wyboru, pójdę z tym.

Eric Sipple

Odpowiedział 03/08/2008 o 15:30
źródło użytkownik

głosy
3

Jeśli planujemy poszukiwania niczego zdalnie przyzwoitej wielkości, najlepiej będzie używać słownika lub zestawu. W przeciwnym razie po prostu trzeba wykonać iterację każdego elementu iteratora, aż dojdziesz do tego chcesz.

Jeśli nie jest to koniecznie wydajność kod wrażliwy, wówczas lista rozumienie sposób powinien działać. Należy jednak pamiętać, że jest to dość nieefektywne, ponieważ przechodzi nad każdym elementem iterator a następnie wraca nad nim ponownie, dopóki nie znajdzie to, co chce.

Pamiętaj, że Python jest jednym z najbardziej efektywnych algorytmów mieszaja wokół. Użyj go na swoją korzyść.

Odpowiedział 27/08/2008 o 21:30
źródło użytkownik

głosy
3

Co myślałem o można osiągnąć używając wyrażeń listowych, ale myślałem, że istnieje funkcja, która zrobiła to w sposób nieco bardziej zwięzłą.

Ie „bar” jest lista obiektów, z których wszystkie mają atrybut „id”

Mityczny sposób funkcjonalny:

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

Sposób lista ze zrozumieniem:

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

Z perspektywy czasu aż lista zrozumienie jest bardzo schludny i tak.

Odpowiedział 03/08/2008 o 17:13
źródło użytkownik

głosy
-1

Myślę:

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

Czy to, co myślisz. Podczas próby sprawdzenia, czy dany klucz istnieje w słowniku w python (wersja Pythona z tabeli mieszania) istnieją dwa sposoby sprawdzenia. Pierwszym z nich jest has_key()sposób przymocowany do słownika i drugi przykład podano powyżej. Zwróci wartość logiczną.

To powinno odpowiedzieć na to pytanie.

A teraz trochę off topic, aby związać się na ten list ze zrozumieniem odpowiedzi poprzednio podanej (na nieco więcej jasności). Listowych skonstruować listę z podstawowego dla pętli z modyfikatorów. Jako przykład (nieco wyjaśnić), sposób korzystania z in dictkonstruktu języka w listowego :

Załóżmy, że masz dwuwymiarowy słownika fooi chcesz tylko drugi wymiar słowniki, które zawierają klucz bar. Stosunkowo prostym sposobem na to byłoby użyć listowych z warunkowym, co następuje:

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

Zauważ, że if bar in valuena końcu zestawienia **, to klauzula modyfikujący, który opowiada listowych , aby tylko utrzymać te pary klucz-wartość, które spełniają warunkowego. ** W tym przypadku bazjest to nowy słownik, który zawiera tylko słowniki z foo które zawierają pasek (mam nadzieję, że nie przegapisz niczego w tym przykładzie kodu ... może trzeba przyjrzeć się dokumentacji listowych znalezionego w docs.python.org tutoriale i na secnetix.de , obie strony są dobre referencje jeżeli pytań w przyszłości.).

Odpowiedział 03/08/2008 o 16:47
źródło użytkownik

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