Wiem, jak używać zarówno do pętli, jak i instrukcji w osobnych wierszach, takich jak:
>>> a = [2,3,4,5,6,7,8,9,0]
... xyz = [0,12,4,6,242,7,9]
... for x in xyz:
... if x in a:
... print(x)
0,4,6,7,9
I wiem, że mogę użyć rozumienia listy, aby połączyć je, gdy stwierdzenia są proste, takie jak:
print([x for x in xyz if x in a])
Ale nie mogę znaleźć nigdzie dobrego przykładu (do skopiowania i uczenia się) demonstrującego złożony zestaw poleceń (nie tylko „print x”), które występują po kombinacji pętli for i niektórych instrukcji if. Coś, czego oczekiwałbym, wygląda:
for x in xyz if x not in a:
print(x...)
Czy to nie tak powinien działać Python?
python
loops
if-statement
for-loop
ChewyChunks
źródło
źródło
for
pętli iif
instrukcji.x in a
jest wolny, jeślia
jest listą.Odpowiedzi:
Możesz użyć wyrażeń generatora takich jak to:
źródło
gen = (y for (x,y) in enumerate(xyz) if x not in a)
zwraca >>>12
podczas pisaniafor x in gen: print x
- więc dlaczego nieoczekiwane zachowanie z wyliczeniem?for x in xyz if x:
for x in (x for x in xyz if x not in a):
działa dla mnie, ale dlaczego nie powinieneś być w stanie to zrobićfor x in xyz if x not in a:
, nie jestem pewien ...Zgodnie z Zen of Python (jeśli zastanawiasz się, czy Twój kod to „ Python ”, to jest miejsce, do którego należy przejść):
Pythoniczny sposób uzyskania dwóch s jest następujący:
sorted
intersection
set
Lub te elementy, które
xyz
nie są wa
:Ale w przypadku bardziej skomplikowanej pętli możesz ją spłaszczyć, wykonując iterację nad dobrze nazwanym wyrażeniem generatora i / lub wywołując dobrze nazwaną funkcję. Próbowanie dopasowania wszystkiego w jednym wierszu rzadko jest „pytoniczne”.
Zaktualizuj po dodatkowych komentarzach do pytania i zaakceptowanej odpowiedzi
Nie jestem pewien, co próbujesz zrobić
enumerate
, ale jeślia
jest słownikiem, prawdopodobnie chcesz użyć klawiszy:źródło
Osobiście uważam, że jest to najładniejsza wersja:
Edytować
jeśli bardzo zależy ci na uniknięciu użycia lambda, możesz użyć częściowej aplikacji funkcji i użyć modułu operatora (który zapewnia funkcje większości operatorów).
https://docs.python.org/2/library/operator.html#module-operator
źródło
filter(a.__contains__, xyz)
. Zwykle, gdy ludzie używają lambda, naprawdę potrzebują czegoś znacznie prostszego.__contains__
jest metodą jak każda inna, tylko jest to metoda specjalna , co oznacza, że może być wywołana pośrednio przez operatora (in
w tym przypadku). Ale można go również wywołać bezpośrednio, jest to część publicznego API. Nazwy prywatne są specjalnie zdefiniowane jako mające co najwyżej jeden końcowy znak podkreślenia, aby zapewnić wyjątek dla specjalnych nazw metod - i podlegają manglowaniu nazw, gdy leksykalnie w zakresach klas. Zobacz docs.python.org/3/reference/datamodel.html#specialnames i docs.python.org/3.6/tutorial/classes.html#private-variables .in
jest wysyłane pojedynczo z odpowiednim operandem). Poza tym zauważ, żeoperator
eksportuje równieżcontains
metodę pod nazwą__contains__
, więc na pewno nie jest to nazwa prywatna. Myślę, że będziesz musiał nauczyć się żyć z faktem, że nie każdy podwójny znak podkreślenia oznacza „trzymaj się z dala”. : -]lambda
potrzeby obejmująnot
:lambda w: not w in a, xyz
Poniżej znajduje się uproszczenie / jedna linijka z zaakceptowanej odpowiedzi:
Zwróć uwagę, że
generator
został utrzymany w linii . Zostało to przetestowanepython2.7
ipython3.6
(zauważ pareny wprint
;))źródło
Prawdopodobnie użyłbym:
źródło
pythonic
wyniki. Mogę kodować funkcjonalnie w każdym innym używanymźródło
import time a = [2,3,4,5,6,7,8,9,0] xyz = [0,12,4,6,242,7,9] start = time.time() print (set(a) & set(xyz)) print time.time() - start
if x in ignore: ...
.if set(a) - set(ignore) == set([]):
więc być może dlatego było to znacznie wolniejsze niż sprawdzanie członkostwa. W przyszłości przetestuję to na znacznie prostszym przykładzie niż to, co piszę.Możesz także użyć generatorów , jeśli wyrażenia generatorów stają się zbyt skomplikowane lub złożone:
źródło
Użyj
intersection
lubintersection_update
skrzyżowanie :
intersection_update :
to
b
jest twoja odpowiedźźródło
Lubiłem odpowiedź Alexa , ponieważ filtr jest akuratnie jeśli stosuje się do listy, więc jeśli chcesz poznać podzbiór listy dany warunek, to wydaje się być najbardziej naturalnym sposobem
metoda ta jest przydatna do rozdzielenia problemów, jeśli zmieni się funkcja warunku, jedynym kodem do manipulowania jest sama funkcja
Metoda generatora wydaje się lepsza, gdy nie chcesz członków listy, ale modyfikacja tych elementów, która wydaje się bardziej dopasowana do generatora
Ponadto filtry działają z generatorami, chociaż w tym przypadku nie jest to wydajne
Ale oczywiście byłoby miło napisać w ten sposób:
źródło
Prosty sposób na znalezienie unikalnych wspólnych elementów list a i b:
źródło