Как распаковать кортеж длины n на m <n переменных

В Python 3 я могу сделать следующее (см. Также PEP3132 об расширенной итеративной распаковке):

a, *b = (1, 2, 3) # a = 1; b = (2, 3) 

Что я могу сделать, чтобы добиться того же самого элегантного в Python 2.x?


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

 a, b = (1, 2, 3)[0], (1, 2, 3)[1:] # a = 1; b = (2, 3) 

  • Matplotlib: интерактивный сюжет на веб-сервере
  • Openshift запускает cron с недопустимой версией python
  • Код продукта выглядит как abcd2343, что разделить на буквы и цифры
  • Как отсортировать список в Python?
  • Как изменить текст метки на языке киви с помощью python
  • Как получить доступ к ключам или значениям Python GDB Value
  • Как отладить lxml.etree.XSLTParseError: неверная ошибка выражения
  • Каков самый простой способ получить tfidf с помощью pandas dataframe?
  • 5 Solutions collect form web for “Как распаковать кортеж длины n на m <n переменных”

    Я узнал, что связанный PEP3132 дает некоторые примеры для Python 2.x:

    Многие алгоритмы требуют разделения последовательности в паре «первый, отдых»:

     first, rest = seq[0], seq[1:] 

    […]

    Кроме того, если правое значение не является списком, но является итерируемым, оно должно быть преобразовано в список, прежде чем сможет выполнять нарезку; чтобы избежать создания этого временного списка, нужно прибегнуть к

     it = iter(seq) first = it.next() rest = list(it) 

    Другие подходы, приведенные в ответах на этот вопрос:

    Список аргументов функции Распаковка

    требует дополнительного определения / вызова функции:

     def unpack(first, *rest): return first, rest first, rest = unpack( *seq ) 

    Интересно, почему он реализован в распаковке списков аргументов функции, но не для обычной распаковки кортежей.

    Подход генератора

    Кредиты . Также требуется реализация пользовательских функций. Является немного более гибким относительно количества первых переменных.

     def unpack_nfirst(seq, nfirst): it = iter(seq) for x in xrange(nfirst): yield next(it, None) yield tuple(it) first, rest = unpack_nfirst(seq, 1) 

    Думаю, что большинство питонов, вероятно, были бы упомянуты в PEP выше?

    У меня есть эта небольшая функция:

     def just(n, seq): it = iter(seq) for _ in range(n - 1): yield next(it, None) yield tuple(it) 

    Например:

     a, b, c = just(3, range(5)) print a, b, c ## 0 1 (2, 3, 4) 

    также работает с меньшими аргументами:

     a, b, c = just(3, ['X', 'Y']) print a, b, c ## XY () 

    В ответ на комментарий вы также можете определить:

     def take2(a, *rest): return a, rest def take3(a, b, *rest): return a, b, rest def take4(a, b, c, *rest): return a, b, rest ... etc 

    и используйте его так:

     p = (1,2,3) a, b = take2(*p) print a, b ## 1 (2, 3) 

    Я не думаю, что есть лучший способ, чем тот, который вы опубликовали, но вот альтернатива, использующая iter

     >>> x = (1,2,3) >>> i = iter(x) >>> a,b = next(i), tuple(i) >>> a 1 >>> b (2, 3) 

    Возможно, я ошибаюсь, но насколько я знаю

     a, *b = (1, 2, 3) 

    это просто синтаксический сахар для нарезки и индексирования кортежей. Я считаю это полезным, но не очень явным.

    Не уверен в контексте, но как насчет .pop (0)?

    Я вижу, что в вашем примере есть кортежи, но если вы хотите сделать то, что делаете, списки будут более подходящими, я думаю? (Если нет веских оснований для того, чтобы они были неизменными, не заданными в вопросе.)

     b = [1,2,3] a = b.pop(0) 
    Python - лучший язык программирования в мире.