2009-11-13 12 views
38

Co jakiś czas tutaj widzę czyjś kod i coś, co wygląda na "jednolinijkową", która jest jednolinijkową instrukcją, która działa w standardowy sposób, w jaki działa tradycyjne polecenie "if" lub pętla "for".Czy jednowierszowe instrukcje "if"/"for" są dobre w stylu Pythona?

Przeszukałem go i nie mogę naprawdę stwierdzić, jakie można wykonać? Czy ktoś może doradzić, a najlepiej podać kilka przykładów?

Na przykład, można zrobić to w jednym wierszu:

example = "example" 
if "exam" in example: 
    print "yes!" 

Lub:

for a in someList: 
    list.append(splitColon.split(a)) 
+1

Nie jesteś pewien, czego szukasz ... możesz wyjaśnić nieco więcej? –

+0

Czy Python nie ma teraz tych dziwacznych rzeczy o lambdzie, które pozwalają ci umieścić o wiele więcej na linii? Oczywiście, że nigdy ich nie użyję. Wolę stary sposób robienia rzeczy :-) – paxdiablo

+1

Nie oglądałem jeszcze lambdy. za każdym razem, gdy widzę to słowo w pytaniu, szybko klikam zakładkę! – Federer

Odpowiedz

50

No

if "exam" in "example": print "yes!" 

Czy ta poprawa? nr. Można nawet dodać więcej instrukcji do treści if -clause, oddzielając je średnikiem. Polecam jednak przeciwko, że chociaż.

+5

Z wyjątkiem kodegolfa, oczywiście, wtedy średniki są ważne :-) – paxdiablo

+0

nie tylko "wydrukowa" tak "" będzie lepiej jak wiemy "" egzamin "w" przykład "" jest prawdziwy –

+8

Anurag: Być może jest powód, dla którego Stephan użył słowa "przykład" w tym segment kodu. – jmucchiello

18

Mówiąc bardziej ogólnie, wszystkie z poniższych kryteriów są ważne składniowo:

if condition: 
    do_something() 


if condition: do_something() 

if condition: 
    do_something() 
    do_something_else() 

if condition: do_something(); do_something_else() 

... itd.

+2

wreszcie średniki .. których szukałem! – holms

+0

Aby było jasne, proszę nie używać takich średników! Próbowałem po prostu całkowicie odpowiedzieć na to pytanie. –

+0

jakikolwiek powód? tha upraszcza moje życie na niektórych instrukcjach if, po których następują instrukcje print, a następnie sys.exit() – holms

3

Można zrobić wszystko to w jednej linii przez pominięcie example zmiennej:

if "exam" in "example": print "yes!" 
6

Python pozwala umieścić wcięty klauzuli na tej samej linii, jeśli jest tylko jedna linia:

if "exam" in example: print "yes!" 

def squared(x): return x * x 

class MyException(Exception): pass 
+1

przykład nie jest zdefiniowany. Potrzebuje wycen. –

+2

Jakiej części przykładu nie rozumiesz? Każdy fragment kodu nie musi deklarować wszystkich swoich zmiennych. – jmucchiello

11

przykład funkcji językowej, która nie tylko usuwa podziały wierszy, ale nadal nie jest przekonana, że ​​jest jaśniejsza niż bardziej szczegółowa wersja:

a = 1 jeśli x> 15 jeszcze 2

7
for a in someList: 
    list.append(splitColon.split(a)) 

można przepisać powyższe jako:

newlist = [splitColon.split(a) for a in someList] 
+2

+1 dla zrozumienia listu – cschol

+0

W pierwszym przypadku używa się 'list', a w drugim używa się' nowej listy'. Czy jest jakaś przyczyna zmiany? – cregox

+1

@Cawas, oh, istotnie. OP użył "listy" w swoim kodzie. Nie jest dobrą praktyką * shadow * wbudowane funkcje lub nazwy typów, np. "Lista". Dlatego w mojej odpowiedzi użyłem "nowej listy". –

38

Odkryłam, że w większości przypadków robi klauzule bloków w jednej linii to zły pomysł.

Będzie to, znowu jako ogólność, obniżyć jakość postaci kodu. Wysokiej jakości kod jest kluczową funkcją języka Pythona.

W niektórych przypadkach Python oferuje sposoby na rzeczy na jednej linii, które są zdecydowanie bardziej pythonic. Rzeczy takie jak co Nick D wspomniano z listy zrozumieniem:

newlist = [splitColon.split(a) for a in someList] 

chociaż chyba trzeba listę wielokrotnego użytku konkretnie można rozważyć użycie generatora zamiast

listgen = (splitColon.split(a) for a in someList) 

uwaga największa różnica między dwoma jest to, że nie można powtórzyć nad generatorem, ale jest bardziej efektywny w użyciu.

Istnieje również wbudowany potrójnego operatora w nowoczesnych wersjach Pythona, które pozwalają robić takie rzeczy jak

string_to_print = "yes!" if "exam" in "example" else "" 
print string_to_print 

lub

iterator = max_value if iterator > max_value else iterator 

Niektórzy ludzie mogą znaleźć one bardziej czytelne i użyteczne niż podobny blok if (condition):.

Jeśli chodzi o to, chodzi o styl kodowania i standard w zespole, nad którym pracujesz. To jest najważniejsze, ale generalnie odradzam jeden blok linii, ponieważ forma kodu w pythonie jest tak ważna.

+0

Znalazłem potrójny operator przydatne dla przypadków takich jak 'logging.info (" Znaleziono% d% s ", num_results," wynik ", jeśli num_results == 1 else" wyniki ")'. – Dennis

+2

Naprawdę bardzo lubię trójząb Pythona. Kiedy już się do tego przyzwyczaisz, jest o wiele bardziej czytelny niż większość języków. Czyni to historyczne '? : 'wydają się być dość archaiczne. –

+0

Dziękuję, to naprawdę pomogło! –

0

Zanurz się w pythonie, w którym mówi o tym, co nazywa and-or trick, co wydaje się skutecznym sposobem włożenia skomplikowanej logiki w jedną linię.

Zasadniczo symuluje operanta potrójnego w c, dając ci możliwość sprawdzenia prawdy i zwrócenia wartości opartej na tym. Na przykład:

>>> (1 and ["firstvalue"] or ["secondvalue"])[0] 
"firstvalue" 
>>> (0 and ["firstvalue"] or ["secondvalue"])[0] 
"secondvalue" 
+1

Uważaj: to * nie * symuluje trójkowego operatora C. '1? 0: 2' jest równe '0', ale' 1 i 0 lub 2' jest równe '2'. Znacznie bezpieczniej jest użyć innego konstruktu, który został stworzony właśnie w tym celu: '0 if 1 else 2' (* daje * 0'). – Stephan202

+0

(Problem w tym przypadku polega na tym, że '0' oznacza' False' Powód, dla którego twój kod * działa *, polega na tym, że '" firstvalue "' oznacza 'True'.) – Stephan202

+0

Ta sztuczka poprzedza operatora trójskładnikowego, i jest w najlepszym razie przybliżeniem, biorąc pod uwagę problemy z wartościami, których wartością logiczną jest Fałsz. – PaulMcG

3

Starsze wersje Pythona pozwoliłby tylko jeden prosty oświadczenie po for ...:if ...: lub podobny blokowych oświadczenia wstępne.

Widzę, że można mieć wiele prostych instrukcji w tym samym wierszu, co dowolny z nich. Istnieją jednak różne kombinacje, które nie działają. Na przykład możemy:

for i in range(3): print "Here's i:"; print i 

... ale z drugiej strony, nie możemy:

for i in range(3): if i % 2: print "That's odd!" 

Możemy:

x=10 
while x > 0: print x; x-=1 

... ale możemy "t:

x=10; while x > 0: print x; x-=1 

... i tak dalej.

W każdym razie wszystkie z nich są uważane za skrajnie nietonogeniczne. Jeśli napiszesz kod w ten sposób, wówczas Pythonistas prawdopodobnie podejmie słabe spojrzenie na twoje umiejętności.

Jest minimalnie dopuszczalne łączenie wielu instrukcji na linii w niektórych przypadkach. Na przykład:

x=0; y=1 

... albo nawet:

if some_condition(): break 

... dla prostych breakcontinue a nawet return oświadczenia lub assigments.

W szczególności, jeśli trzeba użyć jednej serii elif może użyć czegoś takiego:

if  keystroke == 'q': break 
elif keystroke == 'c': action='continue' 
elif keystroke == 'd': action='delete' 
# ... 
else:      action='ask again' 

... to nie może drażnić kolegów zbyt dużo. (Jednak łańcuchy takie jak elif krzyczą, aby zostać refaktoryzowane w stół ekspedycyjny ...słownik, który może wyglądać bardziej podobnie:

dispatch = { 
    'q': foo.break, 
    'c': foo.continue, 
    'd': foo.delete 
    } 


# ... 
while True: 
    key = SomeGetKey() 
    dispatch.get(key, foo.try_again)() 
0

To jest przykład "if" z działaniami.

>>> def fun(num): 
    print 'This is %d' % num 
>>> fun(10) if 10 > 0 else fun(2) 
this is 10 
OR 
>>> fun(10) if 10 < 0 else 1 
1 
Powiązane problemy