Как я могу обойтись без объявления неиспользуемой переменной в цикле for?


87

Если у меня есть понимание списка (например) вроде этого:

['' for x in myList]

Фактически создавая новый список с пустой строкой для каждого элемента в списке, я никогда не использую x . Есть ли более чистый способ написать это, чтобы мне не приходилось объявлять неиспользуемую xпеременную?

Ответы:


130

_ - стандартное имя-заполнитель для игнорируемых элементов в назначении цикла и кортежа, например

['' 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 поддерживает ту же ссылку на тот же объект в памяти.
Mohit Ranka

Имеет ли значение 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 = неиспользуемая-переменная

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.

Еще одна вещь для новичков в Python, таких как я, '_', '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), а i по-прежнему указывает на место, где хранится 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 по-прежнему указывают на одну и ту же ячейку памяти. Другими словами, изменяемые переменные действуют в той же ячейке памяти, на которую указывает переменная, вместо того, чтобы делать копию значения, указанного переменной, как в случае с неизменяемой переменной.


Спасибо за это, но я действительно не знаю, какое это имеет отношение к вопросу. (нет, я не downvote)
Рами
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.