Jak umieścić wiele instrukcji w jednej linii?

143

Nie byłem pewien, pod jakim tytułem dokładnie rozważać to pytanie, kodowanie golfa wydaje się odpowiednie, choć trochę nieokreślone.

Znam trochę rozumień w Pythonie, ale wydają się bardzo trudne do „odczytania”. Tak jak ja to widzę, zrozumienie może osiągnąć to samo, co następujący kod:

for i in range(10): if i == 9: print('i equals 9')

Ten kod jest dużo łatwiejszy do odczytania niż obecne rozumienia, ale zauważyłem, że nie możesz mieć dwóch znaków ``: '' w jednym wierszu ... to też mnie prowadzi ...

moje pytanie:

Czy jest jakiś sposób, żebym mógł umieścić następujący przykład w JEDNEJ LINII.

try:
    if sam[0] != 'harry':
        print('hello',  sam)
except:
    pass

Coś takiego byłoby świetne:

try: if sam[0] != 'harry': print('hellp',  sam)
except:pass

Ale znowu napotykam sprzeczne ``: '' Chciałbym również wiedzieć, czy istnieje sposób na uruchomienie try (lub coś podobnego) bez wyjątku, wydaje się całkowicie bezcelowe, że muszę wstawić wyjątkiem: podaj tam. to zmarnowana linia.

Dziękuję za wkład ... i uśmiechnij się : D

Rhys
źródło
Dlaczego miałby kiedykolwiek zgłosić wyjątek?
Ignacio Vazquez-Abrams
1
sam [2] może nie istnieć. To hipotetyczny przykład. dzięki
Rhys
4
W Pythonie rozumienie jest czymś innym. Umieszczenie wszystkiego w jednym wierszu nie jest zrozumieniem.
Felix Kling
Jestem tego świadomy. dzięki. Właśnie pokazałem, jak myślę, że rozumienie może działać lepiej, ale nie może ze względu na okrężnicę, która jest źródłem mojego problemu / pytania
Rhys
Po prostu użyj \nsi spacji dla wcięć.

Odpowiedzi:

144

Niestety, to, czego chcesz, nie jest możliwe w Pythonie (co sprawia, że ​​Python jest prawie bezużyteczny dla programów jednowierszowych wiersza poleceń). Nawet jawne użycie nawiasów nie pozwala uniknąć wyjątku składni. Możesz uciec z sekwencją prostych instrukcji oddzielonych średnikiem:

for i in range(10): print "foo"; print "bar"

Ale gdy tylko dodasz konstrukcję, która wprowadza wcięty blok (jak if), potrzebujesz znaku końca wiersza. Również,

for i in range(10): print "i equals 9" if i==9 else None

jest legalne i może przybliżać to, czego chcesz.

Jeśli chodzi o try ... exceptrzeczy: Byłoby całkowicie bezużyteczne bezexcept . trymówi „Chcę uruchomić ten kod, ale może zgłosić wyjątek”. Jeśli nie obchodzi Cię wyjątek, zostaw rozszerzenie try. Ale gdy tylko to umieścisz, mówisz „Chcę poradzić sobie z potencjalnym wyjątkiem”. passNastępnie mówi, że nie chce obsługiwać go specjalnie. Ale to oznacza, że ​​twój kod będzie nadal działał, czego inaczej by nie zrobił.

ThomasH
źródło
1
ciekawe, myślę, że twój drugi przykład jest najbliższy odpowiedzi, której szukałem. dzięki
Rhys
w odniesieniu do pytania `` spróbuj '' ... Co jeśli, wiem, że w pewnym momencie spowoduje to zgłoszenie wyjątku, ale chcę tylko, aby kod kontynuował działanie ... na przykład, aby sprawdzić, czy ciąg może być liczbą całkowitą try: int (string) ... Jeśli nie może, po prostu przejdź do następnej linii, bez wyjątku. Rozumiem, o czym mówisz, ale czy jest jakiś inny sposób na tego typu sprawdzanie / obsługę błędów
Rhys,
4
Re try:: Reguły składni Pythona po prostu nie pozwolą ci uciec z pojedynczą klauzulą ​​„try” bez towarzyszącej jej klauzuli „oprócz”. To, co robię, to zawijanie try-behind we własnej funkcji i wywołanie tego zamiast tego. Polub if (checkint(s))...i def checkint(s): try: int(s)\nreturn True\nexcept: return False.
ThomasH
ThomasH, chciałbym, żeby twój komentarz był gdzieś odpowiedzią na pytanie, abym mógł go zagłosować. Doskonały.
Ivan X
5
@ThomasH " (co sprawia, że ​​Python jest prawie bezużyteczny dla programów jednowierszowych wiersza poleceń) ": nie przeszkadza mi. 95% przypadków nie wymaga nowej linii. A reszta za pośrednictwem \ n: python -c "exec\"print 'A' \nfor i in 1,2,3: print i \""
kxr
52

Możesz użyć wbudowanej instrukcji exec, np .:

exec("try: \n \t if sam[0] != 'harry': \n \t\t print('hello',  sam) \nexcept: pass")

Gdzie \njest znakiem nowej linii i \tjest używany jako wcięcie (tabulator).
Należy również policzyć używane spacje, aby wcięcie było dokładnie dopasowane.

Jednak, jak już powiedziały wszystkie inne odpowiedzi, można tego oczywiście używać tylko wtedy, gdy naprawdę musisz umieścić to w jednej linii.

exec jest dość niebezpieczną instrukcją (szczególnie podczas budowania aplikacji internetowej), ponieważ umożliwia wykonanie dowolnego kodu Pythona.

elecprog
źródło
4
Dziękuję Ci! Powinno to zostać oznaczone jako poprawna odpowiedź, ponieważ w rzeczywistości działa, w przeciwieństwie do innych. Ale oczywiście nigdy tego nie rób, chyba że musisz! Jednak faktycznie potrzebuję tej składni, ponieważ muszę wprowadzać skrypty do stałego jednowierszowego pola tekstowego.
Sanjay Manohar,
Dzięki ! Ratownik! Nie używam tego w moim skrypcie, ale w powłoce interaktywnej jest to przydatne do debugowania ... Często po prostu wychodzę z powłoki interaktywnej i uruchamiam ją ponownie, aby uzyskać czyste środowisko, a następnie muszę powtórzyć pewne kroki, np. moduł, uruchamiając niektóre funkcje, a następnie wykonaj test z określoną funkcją. Soooo, szukałem sposobu na umieszczenie "importowania modułu, uruchamiania niektórych funkcji" w onelinerze, abym mógł szybko wywołać go z historii i uruchomić (zamiast wywoływać 5 różnych pozycji z historii) +1
oneindelijk
exec("try: \n if sam[0] != 'harry': print('hello', sam) \nexcept: pass") ładniej :)
kxr
Dziękuję kxr :) (wykorzystałem twój pomysł, aby poprawić odpowiedź)
elecprog
7

Tak, ten post ma 8 lat, ale na wypadek, gdyby ktoś tu przyszedł i szukał odpowiedzi: możesz teraz użyć tylko średników. Jednak nie możesz używać if / elif / else staments, pętli for / while i nie możesz definiować funkcji. Głównym zastosowaniem tego byłoby używanie zaimportowanych modułów, w których nie trzeba definiować żadnych funkcji ani używać żadnych instrukcji / pętli if / elif / else / for / while.

Oto przykład, który bierze artystę utworu, nazwę utworu i wyszukuje genialne słowa:

import bs4, requests; song = input('Input artist then song name\n'); print(bs4.BeautifulSoup(requests.get(f'https://genius.com/{song.replace(" ", "-")}-lyrics').text,'html.parser').select('.lyrics')[0].text.strip())
symbxlz
źródło
6

Nie polecam tego robić ...

To, co opisujesz, nie jest zrozumieniem.

PEP 8 Style Przewodnik dla kodu Pythona , który ja nie polecam, ma do powiedzenia na temat oświadczeń złożonych:

  • Instrukcje złożone (wiele instrukcji w tym samym wierszu) są generalnie odradzane.

Tak:

      if foo == 'blah':
          do_blah_thing()
      do_one()
      do_two()
      do_three()

Raczej nie:

      if foo == 'blah': do_blah_thing()
      do_one(); do_two(); do_three()

Oto przykładowe rozumienie, aby dokonać rozróżnienia:

>>> [i for i in xrange(10) if i == 9]
[9]
Johnsyweb
źródło
6

Nie zachęcam do tego, ale mówię, że jesteś w wierszu poleceń, nie masz nic oprócz Pythona i naprawdę potrzebujesz jednowierszowego kodu, możesz to zrobić:

python -c "$(echo -e "a='True'\nif a : print 1")"

To, co tutaj robimy, to wstępne przetwarzanie \nprzed oceną kodu Pythona.

To super hacky! Nie pisz takiego kodu.

Tiago Lopo
źródło
1

może z „i” lub „lub”

po fałszywej potrzebie napisania „lub”

po prawdziwej potrzebie napisania „i”

lubić

n=0
def returnsfalse():
    global n
    n=n+1
    print ("false %d" % (n))
    return False
def returnstrue():
    global n
    n=n+1
    print ("true %d" % (n))
    return True
n=0
returnsfalse() or  returnsfalse() or returnsfalse() or returnstrue() and returnsfalse()

wynik:

false 1
false 2
false 3
true 4
false 5

a może jak

(returnsfalse() or true) and (returnstrue() or true) and ...

dostałem się tutaj, wyszukując w google "jak umieścić wiele zdań w jednym wierszu pythona", nie odpowiadając bezpośrednio na pytanie, może ktoś inny tego potrzebuje.

Shimon Doodkin
źródło
1

Aby uzyskać python -czorientowane rozwiązanie i pod warunkiem, że używasz powłoki Bash, tak, możesz mieć prostą jednowierszową składnię, jak w tym przykładzie:

Załóżmy, że chcesz zrobić coś takiego (bardzo podobnego do twojej próbki, łącznie z except: passinstrukcją):

python -c  "from __future__ import print_function\ntry: import numpy; print( numpy.get_include(), end='\n' )\nexcept:pass\n" OUTPUT_VARIABLE __numpy_path

To NIE zadziała i spowoduje ten błąd:

  File "<string>", line 1
    from __future__ import print_function\ntry: import numpy; print( numpy.get_include(), end='\n' )\nexcept:pass\n
                                                                                                                  ^
SyntaxError: unexpected character after line continuation character `

Dzieje się tak, ponieważ konkurencja między Bash i Python Interpretation of \nescape sequences. Aby rozwiązać problem, można użyć $'string'składni Bash, aby wymusić \ninterpretację Bash PRZED Pythonem. Aby uczynić ten przykład bardziej wymagającym, dodałem typową end=..\n..specyfikację Pythona w wywołaniu Python print: na końcu będziesz w stanie uzyskać OBIE \ninterpretacje z bash i Python pracujących razem, każdą z odpowiednim fragmentem tekstu. Żeby ostatecznie właściwe rozwiązanie wyglądało tak:

python -c  $'from __future__ import print_function\ntry:\n import numpy;\n print( numpy.get_include(), end="\\n" )\n print( "Hello" )\nexcept:pass\n' OUTPUT_VARIABLE __numpy_path

Prowadzi to do prawidłowego, czystego wyniku bez błędów:

/Softs/anaconda/lib/python3.7/site-packages/numpy/core/include
Hello

Uwaga: powinno to działać również w przypadku execzorientowanych rozwiązań, ponieważ problem jest nadal ten sam (konkurs tłumaczy Bash i Python).

Uwaga 2: można by obejść ten problem, zastępując niektóre \ninnymi, ;ale to nie zadziała w żadnym momencie (w zależności od konstrukcji Pythona), podczas gdy moje rozwiązanie pozwala zawsze na "jednowierszowe" dowolne fragmenty klasycznego wielowierszowego programu w Pythonie.

Uwaga 3: oczywiście, gdy jest to jedna linijka, zawsze należy zadbać o spacje i wcięcia w Pythonie, ponieważ w rzeczywistości nie jesteśmy tutaj ściśle "jednowierszowi", ALE robimy właściwe mieszane zarządzanie \nsekwencją ucieczki między bashem i Pythonem . W ten sposób możemy sobie poradzić z każdym fragmentem klasycznego wielowierszowego programu w Pythonie. Przykład rozwiązania również to ilustruje.

Pierre13fr
źródło
0

Mieszasz wiele rzeczy, co utrudnia odpowiedź na twoje pytanie. Krótka odpowiedź brzmi: O ile wiem, to, co chcesz zrobić, jest po prostu niemożliwe w Pythonie - nie bez powodu!

Dłuższą odpowiedzią jest to, że jeśli chcesz rozwijać się w Pythonie, powinieneś czuć się bardziej komfortowo z Pythonem. Rozumienie nie jest trudne do odczytania. Możesz nie być przyzwyczajony do ich czytania, ale musisz się do tego przyzwyczaić, jeśli chcesz zostać programistą Pythona. Jeśli istnieje język, który lepiej odpowiada Twoim potrzebom, wybierz ten. Jeśli wybierzesz Pythona, bądź przygotowany na rozwiązywanie problemów w Python sposób. Oczywiście możesz walczyć z Pythonem, ale to nie będzie zabawne! ;-)

A jeśli powiesz nam, jaki jest twój prawdziwy problem, możesz nawet uzyskać odpowiedź w języku Python. „Uzyskanie czegoś w jednej linii” zwykle nie jest problemem programistycznym.

Achim
źródło
Uwielbiam Pythona! Właśnie pokazałem, jak myślę, że rozumienie może być lepiej zorganizowane, ale nie może ze względu na okrężnicę, która jest źródłem mojego problemu / pytania ... Po twojej odpowiedzi widzę, że multistatements oddzielone dwukropkami, takie jak try: if sam [ 0]! = 'Harry': print ('hellp', sam) nie są możliwe ... czy to prawda? dzięki ... używam tego tylko do celów debugowania, więc szukam małego, prostego kodu, który można łatwo usunąć i nie zajmuje dużo miejsca lol
Rhys
Tak, o ile wiem, nie jest to możliwe. Ale jak ktoś już powiedział: to, co robisz, różni się od rozumienia. Jeśli chcesz mieć możliwość łatwego usunięcia kodu, umieść go w funkcji. Jeśli chodzi o problem z wyjątkiem: pass, pomyśl o dekoratorze, który ignoruje wyjątek lub coś w tym rodzaju. Znowu: Zawsze staraj się opisać swój prawdziwy problem, a nie problem z rozwiązaniem, które już masz na myśli. ;-)
Achim
3
Dlaczego ludzie muszą zaczynać swoją odpowiedź od nieuzasadnionych prowokacyjnych stwierdzeń, takich jak „mieszasz wiele rzeczy”? Głosuj przeciw, jeśli mogę.
John Jiang,
„Uzyskanie czegoś w jednej linii” zwykle nie jest problemem programistycznym. ”-> ale często jest to problem administratora systemu, więc pytanie jest nadal aktualne w tym aspekcie.
Alex F
0

To możliwe ;-)

# not pep8 compatible^
sam = ['Sam',]
try: print('hello',sam) if sam[0] != 'harry' else rais
except: pass

W Pythonie możesz robić bardzo brzydkie rzeczy, takie jak:

def o(s):return''.join([chr(ord(n)+(13if'Z'<n<'n'or'N'>n else-13))if n.isalpha()else n for n in s])

która jest funkcją dla szyfrowania rot13 / cesa w jednej linii z 99 znakami.

yamm
źródło
-2

Oto przykład:

for i in range (80, 90): print (i, end = "") if (i! = 89) else print (i)

Wyjście: 80 81 82 83 84 85 86 87 88 89

>

JZP
źródło