Aby zadeklarować wiele zmiennych w „tym samym czasie”, zrobiłbym:
a, b = True, False
Ale gdybym miał zadeklarować znacznie więcej zmiennych, robi się coraz mniej elegancko:
a, b, c, d, e, f, g, h, i, j = True, True, True, True, True, False, True ,True , True, True
Czy jest na to lepszy / elegancki / wygodny sposób?
To musi być bardzo podstawowe, ale jeśli użyję listy lub krotki do przechowywania zmiennych, jak powinienem podejść, aby być pomocnym, skoro:
aList = [a,b]
Jest nieważne, musiałbym zrobić:
a, b = True, True
Albo czego mi brakuje?
python
variables
declaration
Trufa
źródło
źródło
Odpowiedzi:
Jak sugerowali inni, jest mało prawdopodobne, że użycie 10 różnych zmiennych lokalnych z wartościami boolowskimi jest najlepszym sposobem na napisanie procedury (zwłaszcza jeśli naprawdę mają one jednoliterowe nazwy :)
W zależności od tego, co robisz, sensowne może być użycie słownika. Na przykład, jeśli chcesz ustawić domyślne wartości logiczne dla zestawu jednoliterowych flag, możesz to zrobić:
Jeśli wolisz, możesz to również zrobić za pomocą jednej instrukcji przypisania:
Drugi parametr
dict
to nie jest do tego przeznaczony: tak naprawdę ma na celu nadpisanie poszczególnych elementów słownika za pomocą argumentów słów kluczowych, takich jakd=False
. Powyższy kod wysadza wynik następującego wyrażenia**
do zestawu argumentów słów kluczowych, które są przekazywane do wywoływanej funkcji. Jest to z pewnością niezawodny sposób tworzenia słowników i wydaje się, że ludzie przynajmniej akceptują ten idiom, ale podejrzewam, że niektórzy mogą uznać go za niepytoniczny.</disclaimer>
Jeszcze innym podejściem, które jest prawdopodobnie najbardziej intuicyjne, jeśli będziesz często używać tego wzorca, jest zdefiniowanie danych jako listy wartości flag (
True
,False
) odwzorowanych na nazwy flag (ciągi jednoznakowe). Następnie należy przekształcić tę definicję danych w odwrócony słownik, który odwzorowuje nazwy flag na wartości flag. Można to zrobić dość zwięźle za pomocą zagnieżdżonych list składanych, ale oto bardzo czytelna implementacja:Funkcja
invert_dict
jest funkcją generatora . To generuje , lub plonów - co oznacza, że wielokrotnie zwraca wartości - par klucz-wartość. Te pary klucz-wartość są odwrotnością zawartości dwóch elementów pierwotnegoflags
słownika. Są wprowadzane dodict
konstruktora. W tym przypadkudict
konstruktor działa inaczej niż powyżej, ponieważ jako argument jest podawany do iteratora, a nie do słownika.Opierając się na komentarzu @Chris Lutz: Jeśli naprawdę będziesz używać tego do wartości jednoznakowych, możesz to zrobić
To działa, ponieważ łańcuchy Pythona są iterowalne , co oznacza, że można je przesuwać przez wartość według wartości. W przypadku łańcucha wartościami są poszczególne znaki w ciągu. Więc kiedy są interpretowane jako iterowalne, jak w tym przypadku, gdy są używane w pętli for,
['a', 'b', 'c']
i'abc'
są w rzeczywistości równoważne. Innym przykładem może być sytuacja, gdy są one przekazywane do funkcji, która przyjmuje iterowalną funkcję, na przykładtuple
.Osobiście nie zrobiłbym tego, ponieważ nie czyta intuicyjnie: kiedy widzę ciąg, spodziewam się, że zostanie on użyty jako pojedyncza wartość, a nie jako lista. Patrzę więc na pierwszą linię i myślę „OK, więc jest flaga Prawda i Flaga fałszu”. Więc chociaż jest taka możliwość, nie sądzę, żeby to była droga. Z drugiej strony może pomóc jaśniej wyjaśnić pojęcia iterowalne i iteratory.
Zdefiniowanie funkcji
invert_dict
tak, aby faktycznie zwracała słownik, również nie jest złym pomysłem; W większości po prostu tego nie robiłem, ponieważ nie pomaga to wyjaśnić, jak działa rutyna.Najwyraźniej Python 2.7 ma wyrażenia słownikowe, co stanowiłoby niezwykle zwięzły sposób implementacji tej funkcji. Czytelnikowi pozostawiam to jako ćwiczenie, ponieważ nie mam zainstalowanego Pythona 2.7 :)
Możesz także łączyć niektóre funkcje z zawsze wszechstronnego modułu itertools . Jak mówią, jest więcej niż jeden sposób, aby to zrobić . Czekaj, ludzie Pythona tego nie mówią. Cóż, w niektórych przypadkach to prawda. Sądzę, że Guido podał nam wyrażenia słownikowe, aby można było to zrobić w jeden oczywisty sposób .
źródło
['a', 'b', 'c']
można to skrócić dolist('abc')
, co inspirujedef truth_values(trues, falses): d = dict.from_keys(list(trues), True); d.update(dict.from_keys(list(falses), False)); return d
używane jakovalues = truth_values("abc", "de")
źródło
(d,)
tworzy krotkę z jednym elementem, która jest typem sekwencji. Typy sekwencji obsługują między innymi dodawanie i mnożenie.a, b, c = ([],)*3
nie tworzy 3 Wykaz wystąpień, ale czynia
,b
ic
wskazując na tej samej instancji.a, b, c = ([] for i in range(3))
. źródło . Aby zachować spójność, możesz również użyć wariantu tego w tej odpowiedzi, tja,b,c,d,e,g,h,i,j = (True for i in range(9))
f=(False i in range(1))
.Użyj listy / słownika lub zdefiniuj własną klasę, aby hermetyzować rzeczy, które definiujesz, ale jeśli potrzebujesz wszystkich tych zmiennych, możesz zrobić:
źródło
To jest rozwinięcie @ Jeff M 's i moich komentarzy.
Kiedy to robisz:
Działa z pakowaniem i rozpakowywaniem krotek. Możesz oddzielić etapy pakowania i rozpakowywania:
Pierwsza linia tworzy zwaną krotkę,
_
która ma dwa elementy, pierwszy o wartości,c
a drugi o wartościd
. Druga linia rozpakowuje_
krotkę do zmiennycha
ib
. To rozbija twoją jedną ogromną linię:Na dwie mniejsze linie:
Daje dokładnie taki sam wynik jak pierwsza linia (w tym ten sam wyjątek, jeśli dodasz wartości lub zmienne do jednej części, ale zapomnisz zaktualizować drugą). Jednak w tym konkretnym przypadku odpowiedź yan jest prawdopodobnie najlepsza.
Jeśli masz listę wartości, nadal możesz je rozpakować. Musisz tylko najpierw przekonwertować go na krotkę. Na przykład, następujące przypisanie wartości od 0 do 9, do każdego z
a
przelotowymj
odpowiednio:EDYCJA: Sprytna sztuczka, aby przypisać je wszystkie jako prawdziwe z wyjątkiem elementu 5 (zmienne
f
):źródło
Kiedy ludzie sugerują „użyj listy, krotki lub innej struktury danych”, mówią, że kiedy masz wiele różnych wartości, na których Ci zależy, nazwanie ich wszystkich osobno jako zmiennych lokalnych może nie być najlepszym sposobem robić rzeczy.
Zamiast tego możesz chcieć zebrać je razem w większą strukturę danych, którą można przechowywać w jednej zmiennej lokalnej.
intuited pokazał, jak można w tym celu użyć słownika, a Chris Lutz pokazał, jak używać krotki do tymczasowego przechowywania przed rozpakowaniem do osobnych zmiennych, ale inną opcją do rozważenia jest użycie
collections.namedtuple
bardziej trwałego pakowania wartości.Więc możesz zrobić coś takiego:
Miejmy nadzieję, że prawdziwy kod używałby bardziej znaczących nazw niż „DataHolder” i oczywiście litery alfabetu.
źródło
DataHolder
staje się po prostu trochę bardziej szczegółowa.W czym właściwie jest problem?
Jeśli naprawdę potrzebujesz lub chcesz 10 a , b , c , d , e , f , g , h , i , j , nie będzie innej możliwości, w takim czy innym czasie, aby napisać a i napisać b i napisać c . ....
Jeśli wartości są różne, będziesz musiał napisać na przykład
to znaczy definiowanie „zmiennych” indywidualnie.
Lub, używając innego pisma, nie musisz używać
_
:lub
.
Jeśli część z nich musi mieć tę samą wartość, to problem polega na tym, że jest za długi, aby go napisać
?
Następnie możesz napisać:
.
Nie rozumiem, na czym dokładnie polega twój problem. Jeśli chcesz napisać kod, jesteś zobowiązany do używania znaków wymaganych przy pisaniu instrukcji i definicji. Co jeszcze ?
Zastanawiam się, czy twoje pytanie nie oznacza, że coś źle zrozumiałeś.
Kiedy się pisze
a = 10
, nie tworzy się zmiennej w znaczeniu „kawałka pamięci, którego wartość może się zmienić”. Ta instrukcja:albo powoduje utworzenie obiektu typu
integer
i wartości 10 oraz powiązanie nazwy „a” z tym obiektem w bieżącej przestrzeni nazwlub ponownie przypisz nazwę „a” w przestrzeni nazw do obiektu 10 (ponieważ „a” został wcześniej powiązany z innym obiektem)
Mówię to, ponieważ nie widzę narzędzia do definiowania 10 identyfikatorów a, b, c ... wskazujących na False lub True. Jeśli te wartości nie zmieniają się podczas wykonywania, dlaczego 10 identyfikatorów? A jeśli się zmienią, po co definiować identyfikatory w pierwszej kolejności? Będą one tworzone w razie potrzeby, jeśli nie zostały wcześniej zdefiniowane
Twoje pytanie wydaje mi się dziwne
źródło
Wygląda na to, że podchodzisz do swojego problemu w niewłaściwy sposób.
Przepisz swój kod, aby użyć krotki lub napisz klasę do przechowywania wszystkich danych.
źródło
Podoba mi się odpowiedź, na którą głosowano najczęściej; jednak ma problemy z listą, jak pokazano.
Jest to omówione bardzo szczegółowo (tutaj) , ale sedno jest to, że
a
ib
to ten sam obiekt za is b
powrotemTrue
(tak samo dlaid(a) == id(b)
). Dlatego zmieniając indeks, zmieniasz indeks obua
ib
, ponieważ są one połączone. Aby rozwiązać ten problem, możesz to zrobić (źródło)Można to następnie użyć jako wariantu górnej odpowiedzi, która daje „pożądane” intuicyjne wyniki
źródło
W twoim przypadku użyłbym YAML.
To elegancki i profesjonalny standard postępowania z wieloma parametrami. Wartości są ładowane z oddzielnego pliku. Możesz zobaczyć kilka informacji w tym linku:
https://keleshev.com/yaml-quick-introduction
Ale łatwiej go wygooglować, bo to standard, są setki informacji na jego temat, możesz znaleźć to, co najlepiej pasuje do twojego rozumienia. ;)
Z poważaniem.
źródło
Podobnie jak JavaScript , możesz również użyć wielu instrukcji w jednej linii w Pythonie
a = 1; b = "Hello World"; c += 3
źródło