Cara membongkar tupel panjang n untuk m

Di Python 3 yang bisa saya lakukan sebagai berikut (lihat juga PEP3132 pada Diperpanjang Iterable Membongkar):

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

Apa yang bisa saya lakukan untuk mencapai hal yang sama demikian pula elegan di Python 2.x?


Saya tahu bahwa saya bisa menggunakan elemen tunggal akses dan mengiris operasi, tapi aku bertanya-tanya jika ada yang lebih pythonic cara. Kode saya sejauh ini:

a, b = (1, 2, 3)[0], (1, 2, 3)[1:]
# a = 1; b = (2, 3)
Mengomentari pertanyaan (4)
Larutan

Saya menemukan bahwa terkait PEP3132 memberikan beberapa contoh untuk Python versi 2.x juga:

Banyak algoritma memerlukan membelah urutan dalam "pertama, istirahat" pasangan:

pertama, sisa = seq[0], seq[1:]

[...]

Juga, jika tangan kanan nilai bukan daftar, tapi iterable, maka harus dikonversi ke daftar sebelum mampu melakukan mengiris; untuk menghindari menciptakan ini daftar sementara, kita harus resor untuk

itu = iter(seq) pertama = it.selanjutnya() sisa = daftar(ini)


Pendekatan-pendekatan lain yang diberikan dalam jawaban untuk pertanyaan ini:

Fungsi Daftar Argumen Membongkar Pendekatan

membutuhkan fungsi tambahan definisi/call:

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

Aku bertanya-tanya mengapa hal ini dilaksanakan dalam membongkar argumen fungsi daftar tapi tidak untuk normal tupel membongkar.

Generator Pendekatan

Kredit. Juga membutuhkan fungsi kustom implementasi. Sedikit lebih fleksibel mengenai jumlah first variabel.

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)

Yang paling pythonic mungkin akan menjadi orang-orang yang disebutkan dalam PEP di atas, saya kira?

Komentar (3)

Saya mungkin salah, tapi sejauh yang saya tahu

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

hanya sintaksis gula untuk mengiris dan pengindeksan tupel. Saya menemukan ini berguna, tetapi tidak sangat eksplisit.

Komentar (4)

I've punya sedikit ini berguna fungsi:

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

Misalnya:

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

juga bekerja dengan sedikit argumen:

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

Dalam menanggapi komentar, anda juga dapat menentukan:

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

dan menggunakannya seperti ini:

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

Saya don't pikir ada cara yang lebih baik dari yang anda diposting, tapi di sini adalah sebuah alternatif menggunakan iter

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

Tidak yakin tentang konteks, tetapi apa yang tentang .pop(0)?

Saya melihat bahwa ada tuple dalam contoh anda, tetapi jika anda ingin melakukan hal-hal yang anda lakukan, daftar akan lebih cocok, saya pikir? (Kecuali ada beberapa alasan yang baik bagi mereka untuk menjadi abadi tidak diberikan dalam pertanyaan.)

b = [1,2,3]
a = b.pop(0)
Komentar (0)