Як я можу обійти оголошення оголошення невикористовуваної змінної у циклі for?


87

Якщо я маю розуміння списку (наприклад), як це:

['' for x in myList]

Ефективно створюючи новий список, який містить порожній рядок для кожного елемента в списку, я ніколи не використовую x. Чи є чистіший спосіб написання цього, щоб мені не потрібно було оголошувати невикористовувану xзмінну?

Відповіді:


130

_ - це стандартне ім’я-заповнювач для ігнорованих членів у призначенні for-loop і кортежу, наприклад

['' for _ in myList]

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

До речі, ваш список можна писати без розуміння списку (припускаючи, що ви хочете скласти список незмінних членів, таких як рядки, цілі числа тощо).

[''] * len(myList)

10
Останнє повинно супроводжуватися величезним попередженням, що воно не робить очікуваних дій для змінних об’єктів.

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

@Ramy: Мохіт опублікував пояснення, але його було видалено: S У будь-якому випадку, перевірте Примітки 2 у docs.python.org/py3k/library/… .
kennytm

2
@Ramy, Python зберігає однакові посилання на той самий об'єкт у пам'яті.
Мохіт Ранка

Чи має значення, чи я, наприклад, роблю вкладені forцикли? Або якщо всередині for _ in range(...)я хочу сказати _, var = f(x)? Чи не буде плутанина між двома _змінними?
Eric Auld

19

Ні. Як пише дзен: особливі випадки недостатньо спеціальні, щоб порушити правила. Особливий випадок, коли цикли не використовують елементи ітерації, і правило полягає в тому, що потрібно розпакувати "ціль".

Однак ви можете використовувати _як ім'я змінної, яке зазвичай розуміється як "навмисно невикористане" (навіть PyLint тощо знає і поважає це).


Однак PyLint скаржиться, що C: 10,24: Invalid variable name "_" (invalid-name)якщо ви не додасте його до good-namesсвого .pylintrc.
giorgiosironi

12

Виявляється, використання dummy*(початкове слово є фіктивним) як імені змінної робить той самий фокус, що і _. _є відомим стандартом, і було б краще використовувати значущі імена змінних. Таким чином , ви можете використовувати dummy, dummy1, dummy_anything. Використовуючи ці імена змінних PyLint, не скаржишся.


Я справді віддаю перевагу такому підходу. це залишається значущим.
RvdK

2

Додайте наступний коментар після циклу for у тому ж рядку:

#pylint: disable = unused-variable

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

1

Якщо вам потрібно назвати свої аргументи (у випадку, наприклад, під час написання макетів, які не використовують певні аргументи, на які посилаються по імені), ви можете додати цей метод ярлика:

def UnusedArgument(_):
  pass

а потім використовувати його так

def SomeMethod(name_should_remain):
  UnusedArgument(name_should_remain)

0

Об'єкти генератора насправді не використовують змінні. Так щось на зразок

list(('' for x in myList))

повинен зробити трюк. Зверніть увагу, що x не визначається як змінна поза розумінням генератора.


0

Ви також можете додати до імені змінної, _якщо ви віддаєте перевагу надавати змінній зручне для читання ім'я. Наприклад , ви можете використовувати _foo, _foo1, _anythingі PyLint НЕ буде скаржитися. У циклі for це було б так:

for _something in range(10):
    do_something_else()

редагувати: Додати приклад


0

Багатослівний спосіб:

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

Ви уникаєте оголошення використаної змінної таким чином.

Також ви можете додавати як змінні, так і незмінні об'єкти (наприклад, словники) в newList.

Інша річ для таких початківців, як я, '_', 'dummy' трохи бентежить.



-1

Коментар до Як я можу обійти оголошення оголошення невикористовуваної змінної у циклі for? (Закінчився розмір коментаря)

Python підтримує те саме посилання на створений об'єкт. (незалежно від змінності), наприклад,

In [1]: i = 1

In [2]: j = 1

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

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

Ви можете бачити як i, так і j, посилаються на один і той же об'єкт у пам'яті. Що відбувається, коли ми змінюємо значення однієї незмінної змінної.

In [5]: j = j+1

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

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

ви можете бачити, що j тепер починає вказувати на нове місце (де зберігається 2), а я все ще вказує на місце, де зберігається 1. Оцінюючи,

j = j+1

Значення вибирається з 142671248, обчислюється (якщо воно ще не кешоване) і поміщається в нове місце 142671236. j робиться для вказівки на нове розташування. Простіше кажучи, нова копія, що робиться щоразу, коли змінюється незмінна змінна.

Змінюваність

Змінні предмети в цьому відношенні діють мало інакше. Коли значення, вказане

In [16]: a = []

In [17]: b = a

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

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

І a, і b вказують на одне і те ж місце в пам'яті.

In [20]: a.append(5)

Розташування пам'яті, вказане символом a, змінено.

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

І a, і b все одно вказують на одне і те ж місце в пам'яті. Іншими словами, змінні змінні діють з тим самим місцем пам'яті, на яке вказує змінна, замість того, щоб копіювати значення, вказане змінною, як у незмінному випадку змінної.


Дякую за це, але я справді не впевнений, яке відношення має до цього питання. (ні, я не голосував проти)
Рамі,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.