Многократное Распаковывание Назначения в Python, когда вы не знаете длину последовательности - PullRequest
13 голосов
/ 28 марта 2010

Примеры из нескольких заданий распаковки в учебнике выглядят примерно так:

import numpy as NP
M = NP.arange(5)
a, b, c, d, e = M
# so of course, a = 0, b = 1, etc.

M = NP.arange(20).reshape(5, 4)     # numpy 5x4 array
a, b, c, d, e = M
# here, a = M[0,:], b = M[1,:], etc. (ie, a single row of M is assigned each to a through e)

(Мой вопрос не специфичен numpy. Действительно, я бы предпочел чисто Python-решение.)

Для фрагмента кода, который я сейчас рассматриваю, я вижу две сложности в этом простом сценарии:

  • Я обычно не знаю форму M;и

  • Я хочу распаковать определенное количество предметов (определенно меньше, чем все предметы), и я хочу поместить остаток в один контейнер

Итак, вернемся к приведенному выше массиву 5x4, и я бы очень хотел назначить первые три строки M соответственно a, b и c (точно так же, как указано выше) и остальные строки (я не знаю, сколько их будет, только некоторое положительное целое число) в один контейнер, all_the_rest = [].

Ответы [ 2 ]

28 голосов
/ 28 марта 2010

Python 3.x может сделать это легко:

a, b, *c = someseq

Python 2.x требует немного больше работы:

(a, b), c = someseq[:2], someseq[2:]
11 голосов
/ 28 марта 2010

Синтаксис для этого добавлен в Python 3

>>> # Python 3.x only
>>> a, b, *c = range(10)
>>> a
0
>>> b
1
>>> c
[2, 3, 4, 5, 6, 7, 8, 9]

но аналогичного решения в Python 2 не существует.

Вы, конечно, можете сделать

>>> s = range(10)
>>> s
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> (a, b, c), rest = s[0:3], s[3:]
>>> a
0
>>> b
1
>>> c
2
>>> rest
[3, 4, 5, 6, 7, 8, 9]

или другие подобные решения.

...