Jak mogę obejść deklarowanie nieużywanej zmiennej w pętli for?


87

Jeśli mam rozumienie listy (na przykład) w ten sposób:

['' for x in myList]

Efektywnie tworząc nową listę, która ma pusty ciąg dla każdego elementu na liście, nigdy nie używam x. Czy istnieje bardziej przejrzysty sposób zapisania tego, abym nie musiał deklarować nieużywanej xzmiennej?

Odpowiedzi:


130

_ to standardowa nazwa zastępcza dla ignorowanych elementów członkowskich w przypisaniu pętli for i krotki, np

['' for _ in myList]

[a+d for a, _, _, d, _ in fiveTuples]

Swoją drogą twoją listę można napisać bez jej rozumienia (zakładając, że chcesz stworzyć listę niezmiennych członków, takich jak ciągi znaków, liczby całkowite itp.).

[''] * len(myList)

10
Temu ostatniemu musi towarzyszyć ogromne ostrzeżenie, że nie robi on oczekiwanej rzeczy w przypadku zmiennych obiektów.

5
@Mohit:a=[[]]*4;a[0].append(5);print(a)
kennytm

@Ramy: Mohit opublikował wyjaśnienie, ale zostało ono usunięte: S W każdym razie sprawdź Notatki 2 w docs.python.org/py3k/library/… .
kennytm

2
@Ramy, Python utrzymuje w pamięci to samo odniesienie do tego samego obiektu.
Mohit Ranka

Czy ma to znaczenie, jeśli forna przykład wykonuję zagnieżdżone pętle? A jeśli w środku for _ in range(...)chcę powiedzieć _, var = f(x)? Czy będzie się mylić między dwiema _zmiennymi?
Eric Auld

19

Nie. Jak to ujął Zen: specjalne przypadki nie są na tyle wyjątkowe, aby łamać zasady. Specjalny przypadek to pętle, które nie używają elementów iterowanej rzeczy, a reguła jest taka, że ​​istnieje „cel” do rozpakowania.

Możesz jednak użyć _nazwy zmiennej, która jest zwykle rozumiana jako „celowo nieużywana” (nawet PyLint itp. Wie o tym i szanuje).


PyLint jednak narzeka, że C: 10,24: Invalid variable name "_" (invalid-name)jeśli nie dodasz go do good-namesswojego .pylintrc.
giorgiosironi

12

Okazuje się, że użycie dummy*(słowo początkowe jest fikcyjne) jako nazwy zmiennej działa tak samo jak _. _to znany standard i lepiej byłoby używać znaczących nazw zmiennych. Więc można użyć dummy, dummy1, dummy_anything. Używając tych nazw zmiennych PyLintnie będziesz narzekać.


Rzeczywiście wolę takie podejście. pozostaje znaczący.
RvdK

2

Dodaj następujący komentarz po pętli for w tym samym wierszu:

#pylint: disable = unused-variable

for i in range(100): #pylint: disable=unused-variable

1

Jeśli chcesz nazwać swoje argumenty (na przykład podczas pisania makiet, które nie używają pewnych argumentów, do których odwołuje się nazwa), możesz dodać tę metodę skrótu:

def UnusedArgument(_):
  pass

a następnie użyj go w ten sposób

def SomeMethod(name_should_remain):
  UnusedArgument(name_should_remain)

0

Obiekty generatora w rzeczywistości nie używają zmiennych. Więc coś w stylu

list(('' for x in myList))

powinien załatwić sprawę. Zauważ, że x nie jest zdefiniowane jako zmienna poza zrozumieniem generatora.


0

Możesz również poprzedzić nazwę zmiennej, _jeśli wolisz nadać zmiennej nazwę czytelną dla człowieka. Na przykład można użyć _foo, _foo1, _anythinga pylint nie będą narzekać. W pętli for wyglądałoby to tak:

for _something in range(10):
    do_something_else()

edycja: Dodaj przykład


0

Szczegółowy sposób to:

newList = []
while len(newList) < len(mylist):
    newList.append('')

W ten sposób unikasz deklarowania używanej zmiennej.

Możesz także dołączać zarówno zmienne, jak i niezmienne obiekty (takie jak słowniki) do newList.

Inna rzecz dla początkujących w Pythonie, takich jak ja, „_”, „dummy” są nieco niepokojące.


0

Spróbuj, to proste:

# Use '_' instead of the variable
for _ in range(any_number):
    do_somthing()

-1

Komentarz do Jak mogę obejść deklarowanie nieużywanej zmiennej w pętli for?(Skończył się rozmiar komentarza)

Python zachowuje to samo odniesienie do utworzonego obiektu. (niezależnie od zmienności), na przykład

In [1]: i = 1

In [2]: j = 1

In [3]: id(i)
Out[3]: 142671248

In [4]: id(j)
Out[4]: 142671248

Widzisz, jak i i j odnoszą się do tego samego obiektu w pamięci. Co się dzieje, gdy zmienimy wartość jednej niezmiennej zmiennej.

In [5]: j = j+1

In [6]: id(i)
Out[6]: 142671248

In [7]: id(j)
Out[7]: 142671236

widać, że j zaczyna teraz wskazywać nową lokalizację (gdzie jest zapisane 2), a i nadal wskazuje na lokalizację, w której jest zapisane 1. Oceniając,

j = j+1

Wartość jest pobierana z 142671248, obliczana (jeśli nie została jeszcze zapisana w pamięci podręcznej) i umieszczana w nowej lokalizacji 142671236. j jest wykonywana w celu wskazania nowej lokalizacji. Mówiąc prościej, nowa kopia tworzona za każdym razem, gdy modyfikowana jest niezmienna zmienna.

Zmienność

Pod tym względem zmienne obiekty zachowują się trochę inaczej. Gdy wartość wskazywana przez

In [16]: a = []

In [17]: b = a

In [18]: id(a)
Out[18]: 3071546412L

In [19]: id(b)
Out[19]: 3071546412L

Zarówno a, jak i b wskazują to samo miejsce w pamięci.

In [20]: a.append(5)

Miejsce w pamięci wskazywane przez a jest modyfikowane.

In [21]: a
Out[21]: [5]

In [22]: b
Out[22]: [5]

In [23]: id(a)
Out[23]: 3071546412L

In [24]: id(b)
Out[24]: 3071546412L

Oba a i b nadal wskazują to samo miejsce w pamięci. Innymi słowy, zmienne zmienne działają w tym samym miejscu w pamięci, na które wskazuje zmienna, zamiast tworzyć kopię wartości wskazywanej przez zmienną, jak w przypadku zmiennej niezmiennej.


Dzięki za to, ale naprawdę nie jestem pewien, co to ma wspólnego z tym pytaniem. (nie, nie głosowałem przeciw)
Ramy
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.