Ненужные части при распаковке кортежа / списка - PullRequest
4 голосов
/ 02 декабря 2011

Python - это все о написании прекрасного кода.Итак, я запускаю pylint, чтобы проверить «красивость» моего кода, когда наталкиваюсь на что-то:

Неиспользуемая переменная 'myvar1'

Из этой частимоего кода:

for myvar1, myvar2 in mylist:
    # Do stuff just using myvar2

mylist - это список кортежей, поэтому я развертываю кортежи в две переменные (myvar1 и myvar2).Я определяю эти две переменные только для того, чтобы развернуть вторую, потому что другая мне не нужна.

Итак, вот мой вопрос: Есть ли способ сказать интерпретатору:развернуть кортеж, но не задавать первую часть (например).На некоторых других языках вы можете сделать что-то вроде:

for _, myvar in mylist:
    # Do stuff with myvar

или

for *, myvar in mylist:
    # Do stuff with myvar

Это означает: Мне не важна первая часть кортежа, я простонужен второй.

ПРИМЕЧАНИЕ: Я знаю, что это может быть вариант для того, что я спрашиваю:

for mytuple in mylist:
    # Do stuff with mytuple[1]

Но это далекоменее читабельный.

Ответы [ 6 ]

7 голосов
/ 05 декабря 2011

В дополнение к ответу @ RaymondHettinger: Pylint также не жалуется на неиспользуемые переменные, если их имена начинаются с одного подчеркивания. Это означает, что вы можете использовать:

for _myvar1, myvar2 in mylist:

получая лучшее из обоих миров:

  • нет предупреждения Pylint,
  • и информация о структуре записи

Это работает и для прототипов функций / методов и позволяет избежать предупреждений о неиспользуемых параметрах, которые вы часто можете получить при выводе из базового класса в OO-среде.

3 голосов
/ 03 декабря 2011

Я пишу for _, myvar2 in mylist, когда хочу подчеркнуть, что используется только myvar2 .

И я пишу for myvar1, myvar2 in mylist, когда хочу напомнить читателю (обычно мне), какова структура записи.

Имя _ - это просто соглашение об именах для однозначного значения. Интерпретатор CPython выполняет для него присвоение переменной так же, как и для любого другого имени переменной (к счастью, * STORE_FAST * - очень дешевая операция). Напротив, интерпретатор PyPy идентифицирует неиспользуемое присвоение переменной как мертвый код, поэтому вы получаете оптимизацию бесплатно независимо от того, как вы ее пишете.

Если вам интересно, как CPython интерпретирует ваш код, модуль dis * может предоставить полезную информацию:

>>> from dis import dis
>>> def f(lot):
        for _, var2 in lot:
            print var2


>>> dis(f)
  2           0 SETUP_LOOP              25 (to 28)
              3 LOAD_FAST                0 (lot)
              6 GET_ITER            
        >>    7 FOR_ITER                17 (to 27)
             10 UNPACK_SEQUENCE          2
             13 STORE_FAST               1 (_)
             16 STORE_FAST               2 (var2)

  3          19 LOAD_FAST                2 (var2)
             22 PRINT_ITEM          
             23 PRINT_NEWLINE       
             24 JUMP_ABSOLUTE            7
        >>   27 POP_BLOCK           
        >>   28 LOAD_CONST               0 (None)
             31 RETURN_VALUE 

Как упоминалось в других постерах, предупреждения от pylint иногда могут быть бессмысленными. Если вы предпочитаете короткое имя переменной в своем коде, просто проигнорируйте жалобу Pylint. Как отметил Фрэнсис Авила, Пилинт не должен жаловаться на _ в этом контексте.

3 голосов
/ 03 декабря 2011

Вы пробовали что-то из этого?

for _, myvar in mylist:
    #Do stuff

отлично работает в Python и относительно идиоматичен.

2 голосов
/ 03 декабря 2011

Я бы сказал, что Python - это все о написании читаемого кода - любая «красота» - это просто побочный эффект.

Первый элемент кортежа может быть удален следующим образом:

for myvar2 in zip(*mylist)[1]:
    # Do stuff with myvar2

Но я не уверен, что действительно рекомендую это.Лично я бы просто использовал:

for myvar1, myvar2 in mylist:
    # Do stuff with myvar2

... и игнорировал бы Pylint.

2 голосов
/ 03 декабря 2011

Я полагаю, вы могли бы сделать это:

for myvar in (t[1] for t in mylist):
    pass

Но, честно говоря, я думаю, что вы должны просто проигнорировать предупреждение Pylint в этом случае - это достаточно красиво и не вызовет путаницы (вот почему выхочу красоты в первую очередь).

0 голосов
/ 03 декабря 2011
tu = [(12,'sea'),(478,'badada'),(789,'zut')]

for x,x in tu:
    print x

результат

sea
badada
zut

!

...