Понимание списка Python с фиктивными именами, идентичными имени итератора: неблагоразумно?
Скажем, я составляю список понимания, который выглядит примерно так:
i = range(5)
a = [f(i) for i in i]
Для некоторой функции f
. Даст ли использование фиктивного имени, идентичного итератору, когда-либо неожиданные результаты? Иногда у меня есть имена переменных, которые являются отдельными буквами, и мне удобнее придерживаться одной и той же буквы, а не назначать новую, например [f(x) for x in x]
вместо [f(i) for i in x]
(например, если буква итератора x
является значимой , я задам себе вопрос, что за черт i
есть).
2 ответа:
TL; DR: это безопасно технически, но это плохой выбор стилистически.
В понимании списка, перед привязкой свободной переменной цикла for к любому объекту, Python будет использовать код операции
GET_ITER
на iterable, чтобы получить итератор. Это делается только один раз в начале цикла.Поэтому в теле "цикла" понимания списка (который фактически создает область в Python 3), Вы можете повторно связать имя, которое первоначально указывало на повторяется без каких-либо последствий. Итерация имеет дело непосредственно со ссылкой на итератор , и неважно, имеет ли он имя в области видимости. То же самое должно быть верно и в Python 2, хотя детали реализации области действия различны: имя коллекции будет потеряно после понимания, так как имя переменной цикла останется привязанным к конечному элементу итерации.
Нет никакого преимущества в написании кода таким образом, и он менее читаем. чем просто избежать столкновения имен. Итак, вы должны предпочесть назвать коллекцию так, чтобы было более очевидно, что это коллекция:
[f(x) for x in xs]
В то время как вы можете избежать использования повторяющихся имен переменных из-за того, как Python выполняет понимание списка - даже вложенное понимание списка - Не делай этого . На ваш взгляд, это может показаться более читаемым, но для большинства людей это будет очень запутанным.
Однако это приводит к гораздо более важному моменту. Зачем использовать такое имя, какi
,j
, илиx
вообще? Использование однобуквенных имен переменных приводит к путанице и неоднозначности. Вместо этого используйте имя переменной, которое ясно передает ваше намерение.Или, если у вас нет необходимости вообще для значений в iterable вашего перебора(например. Вы просто хотите повторить блок кода определенное количество раз), используйте переменную" выбрасывания",
Но не используйте не описательные, повторяющиеся, однобуквенные имена переменных. Это только запутает будущих читателей вашего кода, сделает ваше намерение неясным, и создание кода, который трудно поддерживать и отлаживать._
, чтобы донести до читателя вашего кода, что значение не важно и должно быть проигнорировано.Потому что, в конце концов, вы бы предпочли поддерживать такой код
[str(x) for x in x]
Или это?
[str(user_id) for user_id in user_ids]