2009-10-11 16 views
9
def isBig(x): 
    if x > 4: 
     return 'apple' 
    else: 
     return 'orange' 

To działa:Jak przypisać zmienną w IF, a następnie ją zwrócić. (Python)

if isBig(y): return isBig(y) 

to nie działa:

if fruit = isBig(y): return fruit 

Dlaczego nie 2nd jedną pracę !? Chcę 1-liniowej. Poza tym pierwszy wywoła funkcję DWUKROTNIE.

Jak zrobić 1 linijkę bez wywoływania funkcji dwa razy?

+6

Dlaczego chcesz jedno-liniowy? Programy nie są lepsze, ponieważ mają mniej linii. –

+0

To samo, co http://stackoverflow.com/questions/1513436/what-może--używać-instead-of-assignment-in-an-expression-in-python/1513987#1513987 – PaulMcG

+2

Masz ich 100? Nie napisałbyś parsera, prawda? Zobacz tę listę (http://nedbatchelder.com/text/python-parsers.html) ze strony Neda Batcheldera. – PaulMcG

Odpowiedz

16

widzę ktoś inny już wskazał na mój stary „przypisać i ustaw” Cookbook przepis, który sprowadza się w swej najprostszej wersji do:

class Holder(object): 
    def set(self, value): 
    self.value = value 
    return value 
    def get(self): 
    return self.value 

h = Holder() 

... 

if h.set(isBig(y)): return h.get() 

Jednak ten był przeznaczony głównie do złagodzenia transliteracji między Python i języki, w których przypisanie jest obsługiwane bezpośrednio w if lub while.Jeśli masz „setki” takiego wyboru iz powrotem w kaskadzie, to znacznie lepiej zrobić coś zupełnie innego:

hundreds = isBig, isSmall, isJuicy, isBlah, ... 

for predicate in hundreds: 
    result = predicate(y) 
    if result: return result 

lub nawet coś podobnego

return next(x for x in (f(y) for f in hundreds) if x) 

jeśli jest OK, aby uzyskać wyjątek StopIteration jeśli nie predykat jest spełniony, lub

return next((x for x in (f(y) for f in hundreds) if x)), None) 

jeśli None jest właściwa wartość zwracana, gdy orzeczenie nie jest spełniony , itp.

Prawie niezmiennie, używając (lub nawet chcąc ;-) sztuczka/non-idiom Holder jest "zapachem projektowym", który sugeruje szukanie innego i bardziej Pythonicznego podejścia - jedyny przypadek, w którym Holder jest usprawiedliwienie jest dokładnie tym specjalnym przypadkiem, dla którego go zaprojektowałem, tj. przypadkiem, w którym chcesz zachować ścisłą zgodność między kodem Pythona a jakimś nie-Pythonem (transliteracja algorytmu referencyjnego w Pythonie i chcesz, aby działał najpierw przed refaktoryzacją w bardziej Pythonową formę, lub pisząc Pythona jako prototyp, który będzie transliterowany do C++, C#, Java itd., kiedy będzie działać efektywnie).

0

To nie działa z powodu celowego projektu językowego, ale można użyć this trick obejść tej decyzji

0

Problem polega na tym, że operacja przypisania nie może być oceniane jako posiadające wartość logiczną. Oświadczenie if polega na możliwości oceny wartości logicznej. Na przykład:

>>> fruit = 'apple' 
>>> bool(fruit = 'apple') 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 

/Users/jem/<ipython console> in <module>() 

TypeError: 'fruit' is an invalid keyword argument for this function 
>>> bool('a') 
True 
+0

Nie wiem, bo ma to sens. Wcześniej głosowałem na ciebie :) – TIMEX

+4

(Nie spadłem, ale) Brak powrotu boolowskiego nie jest przyczyną niemożności użycia go w instrukcji 'if()'. Oba te ograniczenia są _ efektami ubocznymi_ języka definiującego przypisanie jako wyrażenie, a nie wyrażenie. –

2

Jeśli chcesz kodować w PHP (lub C), wpisz w nim kod. Nie próbuj wymuszać swoich metod na innym języku.

Jedną z podstawowych zasad Pythona (moim zdaniem) jest jego czytelność. należy używać:

fruit = isBig(y) 
if fruit: return fruit 

Powinienem również wspomnieć, że korzystanie z isXXX() jest bardzo dziwne; zazwyczaj służy do zwracania wartości logicznych. Szczególnie w tym przypadku, gdy używasz go w oświadczeniu IF.

+2

Nie uważam żadnej wersji za mniej lub bardziej czytelną, ale być może z doświadczenia. Ponadto, IMHO jest bardziej konsekwentne, aby uczynić je wyrażeniem, ponieważ '=' wygląda (i jest analizowane, zarówno przez interpreterów i ludzi, jak) jako operator (wyrażenie niejawne), a nie jako funkcja (niejawna instrukcja, chociaż to nie jest " t technicznie prawdziwe). –

+0

Szczerze mówiąc, nie zawsze możesz użyć języka, który chcesz dla projektu, czyniąc tę ​​jedną z najmniej pomocnych odpowiedzi, jakie kiedykolwiek widziałem. Gdybym mógł głosować na ciebie tuzin razy, zrobiłbym to. – Rabbit

+1

Królik, jeśli z jakiegoś powodu wymagane jest używanie określonego języka, należy go właściwie używać. Próba obalenia konstruktów w innych językach jest głupim pomysłem. Widziałem takie dziwaczne rzeczy, jak "#define begin" w kodzie C, ponieważ programiści Pascal nie chcieli się przystosować. Takie zachowanie sprawia, że ​​kod staje się bezużyteczny w językach. – paxdiablo

8

Jedna linijka nie działa, ponieważ w Pythonie przypisanie (fruit = isBig(y)) jest instrukcją, a nie wyrażeniem. W C, C++, Perlu i niezliczonych innych językach jest to wyrażenie i możesz umieścić je w if lub while lub cokolwiek chcesz, ale nie w Pythonie, ponieważ twórcy Pythona uważali, że było to zbyt łatwo nadużywane (lub nadużywane), aby napisać "sprytny" kod (jak próbujesz).

Twój przykład jest raczej głupi. isBig() zawsze oceni na true, ponieważ jedynym łańcuchem, który jest fałszywy, jest pusty ciąg znaków (""), więc Twoja instrukcja if jest w tym przypadku bezużyteczna. Zakładam, że to tylko uproszczenie tego, co próbujesz zrobić. Wystarczy to zrobić:

tmp = isBig(y) 
if tmp: return tmp 

Czy to naprawdę dużo gorsze?

+2

Dziękuję. Przy okazji, gdy masz 100 takich jak to, jest znacznie gorzej :) – TIMEX

+5

Kiedy masz 100 linii w ten sposób, brzmi to tak, jakby twoje rozwiązanie było nieoptymalne, ale nie mogę mówić bez wiedzy, co ty Robię to. –

+1

Co najmniej, przekaż swoje przypadki testowe na listę i wykonaj iterację, aby uniknąć zapisywania ich w ten sposób. –

-3
print "apple" if x > 4 else "orange" 
+0

To nie ma nic wspólnego z pytaniem. –

Powiązane problemy