2016-02-25 23 views
6

Câu hỏi này bắt nguồn từ PEP 448 -- Additional Unpacking Generalizations và có trong Python 3.5 theo như tôi biết (và không được chuyển về 2.x). Cụ thể, trong phần Nhược, sau đây được ghi nhận:Nhà điều hành * sao ở bên trái và bên phải của tuyên bố bài tập

Trong khi *elements, = iterable nguyên nhân elements là một list, elements = *iterable, gây elements là một tuple. Lý do cho điều này có thể gây nhầm lẫn cho những người không quen với cấu trúc.

Mà không thực sự giữ, cho iterable = [1, 2, 3, 4], trường hợp đầu tiên mang lại một list:

>>> *elements, = iterable 
>>> elements 
[1, 2, 3, 4] 

Trong khi đối với trường hợp thứ hai một tuple được tạo ra:

>>> elements = *iterable, 
>>> elements 
(1, 2, 3, 4) 

Là quen với khái niệm , Tôi bị bối rối. Bất cứ ai có thể giải thích hành vi này? Biểu hiện có gắn dấu sao có hoạt động khác nhau tùy thuộc vào bên cạnh nó không?

Trả lời

6

Sự khác biệt giữa hai trường hợp này được giải thích khi cũng xem xét PEP ban đầu để giải nén mở rộng: PEP 3132 -- Extended iterable unpacking.

Trong Tóm tắt cho PEP mà chúng ta có thể thấy rằng:

PEP này đề xuất một sự thay đổi để Iterable giải nén cú pháp, cho phép chỉ định một tên "catch-all" mà sẽ được chỉ định một danh sách của tất cả các mục không được gán cho tên "thông thường".

(tôi nhấn mạnh)

Vì vậy, trong trường hợp đầu tiên, sau khi thực hiện:

*elements, = iterable 

elements luôn sẽ là một list chứa tất cả các mục trong iterable.

Mặc dù nó có vẻ tương tự trong cả hai trường hợp, * trong trường hợp này (bên trái) có nghĩa là: nắm bắt mọi thứ không được gán cho tên và gán cho biểu thức được gắn dấu sao. Nó hoạt động theo cách tương tự như *args**kwargs làm trong các định nghĩa chức năng .

def spam(*args, **kwargs): 
    """ args and kwargs group positional and keywords respectively """ 

Trường hợp thứ hai (bên phải) hơi khác. Ở đây chúng ta không có * làm việc theo cách "nắm bắt mọi thứ" nhiều như chúng ta có nó hoạt động như thường lệ trong các cuộc gọi hàm . Nó mở rộng nội dung của iterable nó được gắn vào.Vì vậy, tuyên bố:

elements = *iterable, 

có thể được xem như là:

elements = 1, 2, 3, 4, 

mà là một cách khác cho một tuple được khởi tạo.

Đỗ Đáng chú ý, một list có thể được tạo ra bởi đơn giản sử dụng elements = [*iterable] mà sẽ giải nén các nội dung của iterable trong [] và kết quả là một bài tập có dạng elements = [1, 2, 3, 4].

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