2012-05-10 25 views
60

Có cách nào để giải nén một danh sách trong phần tử đầu tiên và "đuôi" trong một lệnh duy nhất không?đầu trăn và đuôi ở một dòng

Ví dụ:

>> 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] 
+7

Hãy nhớ rằng danh sách không được triển khai dưới dạng danh sách được liên kết đơn lẻ bằng Python, vì vậy thao tác này tốn kém (như trong: toàn bộ danh sách cần được sao chép). Tùy thuộc vào những gì bạn muốn đạt được, điều này có thể hoặc không có thể là một vấn đề. Tôi chỉ đề cập rằng vì loại phá hoại danh sách này thường được tìm thấy trong các ngôn ngữ chức năng, nơi nó thực sự là một hoạt động rất rẻ. –

Trả lời

126

Dưới Python 3.x, bạn có thể làm điều này độc đáo:

>>> head, *tail = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] 
>>> head 
1 
>>> tail 
[1, 2, 3, 5, 8, 13, 21, 34, 55] 

Một tính năng mới trong 3.x là sử dụng các nhà điều hành * ở giải nén, để có nghĩa là bất kỳ giá trị bổ sung nào. Nó được mô tả trong PEP 3132 - Extended Iterable Unpacking. Điều này cũng có lợi thế là làm việc trên bất kỳ lặp lại, không chỉ trình tự.

Nó cũng là thực sự có thể đọc được.

Như đã trình bày trong PEP, nếu bạn muốn làm tương đương dưới 2.x (không có khả năng thực hiện một danh sách tạm thời), bạn phải làm điều này:

it = iter(iterable) 
head = it.next() 
tail = list(it) 

Đương nhiên, nếu bạn đang làm việc trên một danh sách, cách dễ nhất mà không có cú pháp 3.x là:

head, tail = seq[0], seq[1:] 
+1

xin lỗi, tôi đã sử dụng thuật ngữ đuôi không chính xác. Ý tôi là những gì tôi nói trong ví dụ, đó là danh sách không có phần tử đầu tiên –

+0

@ Giacomod'Antonio Sai lầm của tôi, tôi đã không đọc kỹ đủ. Những gì bạn nói là ý nghĩa bình thường của đuôi. Trên thực tế, điều đó làm cho nó thậm chí còn đơn giản hơn. –

+0

+1 cho Python 2.x và 3.x giải pháp – Patrick

31
>>> mylist = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] 
>>> head, tail = mylist[0], mylist[1:] 
>>> head 
1 
>>> tail 
[1, 2, 3, 5, 8, 13, 21, 34, 55] 
3

Python 2, sử dụng 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] 
6

Đối với O (1) phức tạp của hoạt động head,tail bạn nên sử dụng deque.

Sau cách:

from collections import deque 
l = deque([1,2,3,4,5,6,7,8,9]) 
head, tail = l.popleft(), l 

Nó rất hữu ích khi bạn phải lặp qua tất cả các yếu tố của danh sách. Ví dụ trong việc hợp nhất ngây thơ 2 phân vùng trong sắp xếp hợp nhất.

+0

Có vẻ như deque (list_instance) có độ phức tạp O (N). Liệu tôi có sai? –

+1

@ НикитаКонин, bạn đúng về xây dựng deque. Tuy nhiên, nếu bạn muốn truy cập phần tử đầu tiên nhiều lần, thì 'đầu, đuôi = l.popleft(), l' là ~ O (1). 'head, tail = seq [0], seq [1:]' là O (n). –

Các vấn đề liên quan