Mam listę obiektów. Chcę znaleźć jeden (pierwszy lub dowolny) obiekt na tej liście, który ma atrybut (lub wynik metody - cokolwiek) równy value
.
Jak najlepiej to znaleźć?
Oto przypadek testowy:
class Test:
def __init__(self, value):
self.value = value
import random
value = 5
test_list = [Test(random.randint(0,100)) for x in range(1000)]
# that I would do in Pascal, I don't believe isn't anywhere near 'Pythonic'
for x in test_list:
if x.value == value:
print "i found it!"
break
Myślę, że korzystanie z generatorów reduce()
nie robi żadnej różnicy, ponieważ wciąż będzie iterować po liście.
ps .: Równanie do value
jest tylko przykładem. Oczywiście chcemy uzyskać element spełniający dowolny warunek.
Odpowiedzi:
Pobiera pierwszy element z listy, który pasuje do warunku, i zwraca,
None
jeśli żaden element nie pasuje. To moja preferowana forma pojedynczego wyrażenia.Jednak,
Naiwna wersja z pętlą, jest doskonale Pythonic - jest zwięzła, przejrzysta i wydajna. Aby dopasować go do zachowania jednowarstwowego:
Przydzieli
None
to,x
jeśli nie wyjdzieszbreak
z pętli.źródło
... if getattr(x, x.fieldMemberName) == value
. Spowoduje to pobranie atrybutux
z zachowaną nazwąfieldMemberName
i porównanie go zvalue
.else
Klauzula ma być wfor
pętli, a nieif
. (Odrzucona edycja).Ponieważ nie wspomniano o tym tylko dla uzupełnienia. Dobry stary filtr do filtrowania twoich elementów.
Programowanie funkcjonalne ftw.
Wiem, że ogólnie w liście pythonów preferowane są wyrozumiałości, a przynajmniej tak czytam, ale nie uważam tego za szczery. Oczywiście Python nie jest językiem FP, ale Map / Reduce / Filter są doskonale czytelne i są najbardziej standardowymi standardowymi przypadkami użycia w programowaniu funkcjonalnym.
Więc proszę bardzo. Poznaj swoje programowanie funkcjonalne.
lista warunków filtrów
Nie będzie łatwiejsze niż to:
źródło
filter
zwraca listę niezgodną znext
. 2 : wymaga określonego dopasowania, w przeciwnym razie otrzymaszStopIteration
wyjątek.Prosty przykład : mamy następującą tablicę
Teraz chcemy znaleźć obiekt w tablicy o identyfikatorze równym 1
next
ze zrozumieniem listyDane wyjściowe wszystkich powyższych metod to
{'id': 1, 'name': 'ronaldo'}
źródło
Właśnie natknąłem się na podobny problem i opracowałem małą optymalizację dla przypadku, w którym żaden obiekt na liście nie spełnia wymagań (w moim przypadku użycia spowodowało to znaczną poprawę wydajności):
Wraz z listą test_list przechowuję dodatkowy zestaw test_value_set, który składa się z wartości listy, na których muszę filtrować. Więc tutaj inna część rozwiązania agf staje się bardzo szybka.
źródło
Możesz zrobić coś takiego
Tego właśnie używam do znajdowania obiektów w długim szeregu obiektów.
źródło
Możesz także zaimplementować bogate porównanie
__eq__
metodami dla swojejTest
klasy iin
operatorem. Nie jestem pewien, czy jest to najlepszy samodzielny sposób, ale w przypadku, gdy trzeba porównaćTest
instancje oparte navalue
innym miejscu, może to być przydatne.źródło
Dla kodu poniżej xGen jest anonimowym wyrażeniem generatora, yFilt jest obiektem filtru. Zauważ, że dla xGen zwracany jest dodatkowy parametr None zamiast rzucania StopIteration po wyczerpaniu listy.
Wynik:
źródło