15
>>> LOL = [[1, 2], ['three']] 
>>> [*LOL[0], *LOL[1]] 
[1, 2, 'three'] 

Được rồi! Tạm biệt itertools.chain. Chưa bao giờ thích bạn nhiều.Nói chung mở rộng

>>> [*L for L in LOL] 
    File "<ipython-input-21-e86d2c09c33f>", line 1 
    [*L for L in LOL] 
    ^
SyntaxError: iterable unpacking cannot be used in comprehension 

Oh. Tại sao chúng ta không thể có những điều tốt đẹp?

Giải nén trong một sự hiểu biết có vẻ là hiển nhiên/pythonic, nhưng vì họ đã làm phiền thêm thông báo lỗi đặc biệt đó là lý do vô hiệu hóa nó. Vậy, vấn đề với cú pháp đó là gì?

+1

bạn thêm vòng lặp thứ hai: '[mục cho L trong LOL cho mục trong L]' Có thể loại bỏ sự mơ hồ là cái nào nên được sử dụng. –

+1

Điều này đã không được loại trừ cho tương lai (việc triển khai ban đầu * đã * từ những gì tôi biết), tìm kiếm các tài liệu tham khảo về điều này. –

+3

Xem thông báo chấp nhận [trên py-dev, có một đoạn trên comps.] (Https://mail.python.org/pipermail/python-dev/2015-February/138564.html) –

Trả lời

11

Lấy một trích dẫn từ the Py-Dev mailing list thread in which this feature was accepted:

Vì vậy mà lá comprehensions. IIRC, trong quá trình phát triển bản vá, chúng tôi nhận thấy rằng f(*x for x in xs)đủ mơ hồ mà chúng tôi quyết định không cho phép - lưu ý rằng f(x for x in xs) đã là một trường hợp đặc biệt vì đối số chỉ có thể là biểu thức trình phát "trần" nó là đối số duy nhất. Lý do tương tự không áp dụng (trong biểu mẫu đó) để liệt kê, thiết lập và hiểu thấu đáo - trong khi f(x for x in xs) giống hệt với f((x for x in xs)), [x for x in xs] KHÔNG giống như [(x for x in xs)] (đó là danh sách một phần tử và phần tử là máy phát điện biểu)

(tôi nhấn mạnh)

tôi cũng liếc nhìn vấn đề theo dõi Python cho tính năng này. Tôi đã tìm thấy một vấn đề trong đó thảo luận diễn ra trong khi thực hiện nó. Trình tự của các thông điệp đã giúp họ đi đến hiện thực này bắt đầu here với một cái nhìn tổng quan tốt đẹp về sự mơ hồ được giới thiệu được trình bày trong msg234766 bởi GvR.

Trong sợ liên kết-thối, tôi gắn các tin nhắn (định dạng) ở đây:

Vì vậy, tôi nghĩ rằng chức năng kiểm tra ở đây nên là:

def f(*a, **k): print(list(a), list(k)) 

Sau đó, chúng ta có thể thử những thứ như:

f(x for x in ['ab', 'cd']) 

in đối tượng trình tạo bởi vì điều này được hiểu là đối số đó là một biểu hiện máy phát điện.

Nhưng bây giờ chúng ta hãy xem xét:

f(*x for x in ['ab', 'cd']) 

Cá nhân tôi nghĩ đây chỉ là tương đương với:

f(*'ab', *'cd') 

IOW:

f('a', 'b', 'c', 'd') 

Các PEP không cung cấp rõ ràng về phải làm gì ở đây Câu hỏi bây giờ là, chúng ta có nên giải thích những thứ như *x for x in ... dưới dạng biểu mẫu trình tạo máy được mở rộng hay dưới dạng dạng mở rộng là *arg? Tôi bằng cách nào đó nghĩ rằng sau này là hữu ích hơn và cũng là phần mở rộng hợp lý hơn.

lập luận của tôi là PEP hỗ trợ những thứ như f(*a, *b) và nó sẽ là khá hợp lý để giải thích f(*x for x in xs) như làm điều *x cho mỗi x trong danh sách xs.

Cuối cùng, như đã nêu trong the Abstract section of the corresponding PEP, tính năng này không hoàn toàn loại trừ khả năng:

PEP này không bao gồm giải nén các nhà khai thác trong danh sách, thiết lập và comprehensions từ điển mặc dù này chưa được loại trừ cho các đề xuất trong tương lai.

Vì vậy, chúng tôi có thể sớm thấy nó (chắc chắn không phải 3.6, mặc dù :-) và tôi hy vọng chúng tôi làm, họ trông thật đẹp.

+2

IOW = "nói cách khác" (phải google) – wim

+0

@wim Vì chúng ta đang trung thực ở đây, tôi cũng vậy. –

8

Đây là ngắn gọn giải thích trong PEP 448 trong đó giới thiệu khái quát giải nén: lặp

trước của PEP này cho phép giải nén các nhà khai thác trong danh sách , thiết lập, và comprehensions điển như một nhà điều hành phẳng trên iterables của container :

>>> ranges = [range(i) for i in range(5)] 
>>> [*item for item in ranges] 
[0, 0, 1, 0, 1, 2, 0, 1, 2, 3] 

>>> {*item for item in ranges} 
{0, 1, 2, 3} 

Điều này đã được đáp ứng với sự kết hợp các mối quan tâm mạnh về khả năng đọc và nhẹ su pport. Để không làm bất lợi các khía cạnh ít gây tranh cãi hơn của PEP, điều này đã không được chấp nhận với phần còn lại của đề xuất.

Tuy nhiên, điều này có thể thay đổi trong tương lai:

PEP này không bao gồm giải nén các nhà khai thác trong danh sách, thiết lập và comprehensions từ điển mặc dù điều này chưa được loại trừ khả năng đề xuất trong tương lai.

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