Apakah ada cara pythonic untuk membongkar daftar di elemen pertama dan "tail" dalam satu perintah?
Sebagai contoh:
>> head, tail = **some_magic applied to** [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
>> head
1
>>> tail
[1, 2, 3, 5, 8, 13, 21, 34, 55]
Apakah ada cara pythonic untuk membongkar daftar di elemen pertama dan "tail" dalam satu perintah?
Sebagai contoh:
>> head, tail = **some_magic applied to** [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
>> head
1
>>> tail
[1, 2, 3, 5, 8, 13, 21, 34, 55]
Jawaban:
Di bawah Python 3.x, Anda dapat melakukan ini dengan baik:
>>> head, *tail = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
>>> head
1
>>> tail
[1, 2, 3, 5, 8, 13, 21, 34, 55]
Fitur baru di 3.x adalah menggunakan *
operator dalam membongkar, yang berarti nilai tambahan apa pun. Ini dijelaskan dalam PEP 3132 - Extended Iterable Unpacking . Ini juga memiliki keuntungan untuk mengerjakan iterable apa pun, bukan hanya urutan.
Ini juga sangat mudah dibaca.
Seperti dijelaskan dalam PEP, jika Anda ingin melakukan hal yang setara di bawah 2.x (tanpa berpotensi membuat daftar sementara), Anda harus melakukan ini:
it = iter(iterable)
head, tail = next(it), list(it)
Seperti disebutkan dalam komentar, ini juga memberikan kesempatan untuk mendapatkan nilai default head
daripada membuat pengecualian. Jika Anda menginginkan perilaku ini, gunakan next()
argumen opsional kedua dengan nilai default, yang next(it, None)
akan memberi Anda None
jika tidak ada elemen head.
Biasanya, jika Anda mengerjakan daftar, cara termudah tanpa sintaks 3.x adalah:
head, tail = seq[0], seq[1:]
__getitem__
/ __setitem__
melakukan operasi tail dengan malas, tetapi daftar bawaan tidak.
python 3.x
Untuk kompleksitas head,tail
operasi O (1), Anda harus menggunakan deque
.
Cara berikut:
from collections import deque
l = deque([1,2,3,4,5,6,7,8,9])
head, tail = l.popleft(), l
Ini berguna ketika Anda harus mengulangi semua elemen daftar. Misalnya dalam menggabungkan 2 partisi secara naif dalam merge sort.
head, tail = l.popleft(), l
~ O (1). head, tail = seq[0], seq[1:]
adalah O (n).
head = l.popleft()
dan tail
hanya alias untuk l
. Jika l
perubahan tail
perubahan juga.
Python 2, menggunakan lambda
>>> head, tail = (lambda lst: (lst[0], lst[1:]))([1, 1, 2, 3, 5, 8, 13, 21, 34, 55])
>>> head
1
>>> tail
[1, 2, 3, 5, 8, 13, 21, 34, 55]
head, tail = lst[0], lst[1:]
? jika OP berarti menggunakan literal maka dia bisa membelah kepala dan ekor secara manualhead, tail = 1, [1, 2, 3, 5, 8, 13, 21, 34, 55]
lst = ...
di baris sebelumnya). (2) Melakukan head, tail = lst[0], lst[1:]
membuat kode terbuka untuk efek samping (pertimbangkan head, tail = get_list()[0], get_list()[1:]
), dan berbeda dari bentuk Op head, tail = **some_magic applied to** [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
.
Membangun solusi Python 2 dari @GarethLatty , berikut ini adalah cara untuk mendapatkan satu baris yang setara tanpa variabel perantara di Python 2.
t=iter([1, 1, 2, 3, 5, 8, 13, 21, 34, 55]);h,t = [(h,list(t)) for h in t][0]
Jika Anda membutuhkannya untuk menjadi pengecualian-bukti (yaitu mendukung daftar kosong), maka tambahkan:
t=iter([]);h,t = ([(h,list(t)) for h in t]+[(None,[])])[0]
Jika Anda ingin melakukannya tanpa titik koma, gunakan:
h,t = ([(h,list(t)) for t in [iter([1,2,3,4])] for h in t]+[(None,[])])[0]