Operator trójargumentowy w Pythonie bez innego


85

Czy można to zrobić w jednym wierszu w Pythonie?

if <condition>:
    myList.append('myString')

Wypróbowałem operator trójskładnikowy:

myList.append('myString' if <condition>)

ale moje IDE ( MyEclipse ) nie podobało się, bez pliku else.


1
Masz na myśli operatora trójskładnikowego, który nie ma trzech części? Czy nie jest to sprzeczność terminów?
user207421

Odpowiedzi:


119

Tak, możesz to zrobić:

<condition> and myList.append('myString')

Jeśli <condition>jest fałszywe, włączy się zwarcie, a prawa strona nie zostanie oceniona. Jeśli <condition>jest prawdziwe, zostanie oceniona prawa strona, a element zostanie dołączony.

Zaznaczę tylko, że zrobienie powyższego jest całkiem nie-pythonowe i prawdopodobnie najlepiej byłoby napisać to, niezależnie od:

if <condition>: myList.append('myString')

Demonstracja:

>>> myList = []
>>> False and myList.append('myString')
False
>>> myList
[]
>>> True and myList.append('myString')
>>> myList
['myString']

10
Chociaż ta odpowiedź jest poprawna technicznie, nie jest to dobra praktyka programistyczna. Ponieważ Python ma być językiem, który jest łatwo czytelny, ten kod zostałby uznany za nie-Pythonowy.
Mr. Lance E Sloan

10
@LS: Zgadzam się, dlatego powiedziałem, że prawdopodobnie najlepiej będzie użyć po prostu instrukcji if. Ale zmodyfikowałem nieco odpowiedź, aby była jaśniejsza.
Claudiu

2
fyi drugi przykład nie przejdzie kontroli pep8: E701 multiple statements on one linewięc także nie-pythonowy ...;)
Cas

1
@hard_working_ant „Właściwy” sposób byłby x = object.get('attribute')w tym przypadku
wihlke,

1
@wihlke: tak i dalsze dodawanie x = object.get ('atrybut', brak) do domyślnej wartości Brak
hard_working_ant

45

Powód, dla którego język nie pozwala na użycie składni

variable = "something" if a_condition

bez elsejest to, że w przypadku a_condition == False, gdy variablenagle jest nieznane. Może mogłoby tak być domyślnie None, ale Python wymaga, aby wszystkie przypisania zmiennych w rzeczywistości skutkowały jawnymi przypisaniami. Dotyczy to również przypadków, takich jak wywołania funkcji, jako wartość przekazana do funkcji jest oceniany tak jak RHS instrukcji przypisania będzie.

Podobnie, wszystkie returns muszą faktycznie powrócić, nawet jeśli są warunkowe return. Na przykład:

return variable if a_condition

nie jest dozwolone, ale

return variable if a_condition else None

jest dozwolone, ponieważ drugi przykład gwarantuje, że jawnie coś zwróci.


1
To ironiczne, że Python nie pozwala nam tego używać, więc zmienna nigdy nie variable=Nonejest żadna, ale jest całkowicie legalna. : D
Guy,

1
Ale chciałem tego użyć w ten sposób: continue if i == 0w pętli for.
karantan

2
Czy możesz to zrobićelse pass?
OldBunny2800

5
else passnie działa, ponieważ wyrażenie trójargumentowe powinno zwracać wartość, do której można przekazać return. passnie jest prawidłową returnwartością.
Emmett Butler

4
Nie zgadzam się, że ta motywacja jest prawdziwym powodem, biorąc pod uwagę to if a_condition: variable = "something"i if a_condition: return variablesą legalne. Jest to więc zasadniczo arbitralny wybór składniowy języka Python.
oulenz,

13
if <condition>: myList.append('myString')

W przeciwnym razie nie. Dlaczego trzeba umieścić to w jednej linii?

Zauważ, że „operator trójskładnikowy” to operator . Jak każdy operator, musi coś zwrócić , więc jak można mieć operator trójskładnikowy bez elseklauzuli? Co ma zwrócić, jeśli warunek nie jest prawdziwy?


10

Zasadniczo prosisz o do_thing() if <condition> else passkonstrukt (który wyrzuci SyntaxError, jeśli zostanie uruchomiony). Jak odkryłem podczas badań, podobne pytanie (nieco) do_thing() if condition else Nonejest tak bliskie, jak tylko możesz (co jest po prostu innym sposobem <condition> and do_thing()). Podsumowując ten pomysł i inne odpowiedzi, oto opcje:

  • if <condition>: myList.append('myString') - wydaje się najmniej „hacky” (a zatem preferowany) sposób
  • <condition> and myList.append('myString')
  • myList.append('myString') if <condition> else None

Najmniej hakerski sposób nie działa. Przynajmniej nie na REPL - pojawia się błąd składniowy. Wygląda na to, że jest to spowodowane poprzednim kodem w tym samym wierszu. Zamiast tego należy to wykonać we własnej linii. Ale nawet wtedy wejście użytkownika jest wymagane, aby pominąć wielokropek.
Unknow0059

3

myList.extend(['myString'] if condition else []) również zadziała, chociaż to więcej pracy niż inne rozwiązania.


0

Możesz zrobić coś takiego:

myList.append('myString') if <condition> else False

lub

myList.append('myString') if <condition> else 0

Fałsz i 0 nie są dołączane do listy. Linia musi tylko zwrócić coś, jeśli warunek nie jest spełniony. Możesz zamienić 0 lub Fałsz na Brak lub pusty ciąg lub cokolwiek chcesz, i nie wpłynie to na listę.
Zachary Chiodini

Myślę, że wtedy moja myśl dotyczyła rozumienia listy. Usunąłem mój komentarz, nie oddałem głosu. Przypuszczam, że lepszym sposobem byłoby zrobienie tego, myList.append('myString') if True else _ale jeśli nie przypisujesz niczego, nie ma to znaczenia. Martwię się jednak, że ta osoba próbuje zrozumieć listę z podobną logiką.
Dave Liu

0

Zrobiłbym to po prostu, jeśli chcę dodać opcjonalne elementy do listy na podstawie warunku.

nums = [
        1,
        2,
        3 if <condition> else None,
        4,
       ]
nums = [i for i in nums if i is not None]

to po prostu zastępuje wartość wartością Brak, jeśli warunek nie jest spełniony, a następnie po prostu ponownie definiuje listę bez wartości Brak. w ten sposób zachowują swój indeks, jeśli warunek jest spełniony

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.