Tại sao việc tạo một danh sách các bộ dữ liệu bằng cách sử dụng tính năng hiểu danh sách cần có dấu ngoặc đơn?


8

Như đã lưu ý trong Lập trình chức năng HOWTO , để tạo một danh sách các bộ dữ liệu bằng cách sử dụng tính năng hiểu danh sách, phải sử dụng dấu ngoặc đơn. Đặc biệt, điều này được thể hiện trong tài liệu trong trích dẫn sau đây.

Để tránh đưa ra một sự mơ hồ vào ngữ pháp của Python, nếu biểu thức tạo ra một tuple, thì nó phải được bao quanh bằng dấu ngoặc đơn.

Vì vậy, như ví dụ:

[x, y for x in seq1 for y in seq2]  # This is a syntex error
[(x, y) for x in seq1 for y in seq2]  # This is a correct expression of list of tuples using list comprehension

Sự mơ hồ nào có thể tránh được bằng cách buộc sử dụng dấu ngoặc đơn trong việc thể hiện một danh sách các bộ dữ liệu bằng cách hiểu danh sách?


1
@Georgy: Thật không may, câu trả lời hiện được chấp nhận cho câu hỏi đó là sai. (Đó là những gì tôi đã đoán trước khi tìm thấy xác nhận khác, nhưng nó vẫn sai.)
user2357112 hỗ trợ Monica

Xem thêm Tại sao các bộ dữ liệu trong một danh sách hiểu cần có dấu ngoặc đơn? , trong đó có câu trả lời không chính xác @ user2357112 đề cập đến.
John Kugelman

Câu trả lời:


9

Sau khi đào rất nhiều danh sách gửi thư, tôi đã tìm thấy một tuyên bố khá rõ ràng rằng trình phân tích cú pháp là tốt với nó. Các dấu ngoặc đơn được thực hiện bắt buộc để làm cho ý nghĩa rõ ràng hơn. Đây là một trích dẫn từ Guido trở lại vào năm 2000 trong danh sách gửi thư của python-dev:

Đừng lo lắng. Greg Ewing không có vấn đề gì trong việc diễn đạt điều này bằng ngữ pháp của Python, vốn bị hạn chế như các trình phân tích cú pháp. (Đó là LL (1), tương đương với dòng dõi đệ quy thuần túy với một mã thông báo tìm kiếm, tức là không quay lại.)

Đây là ngữ pháp của Greg:

atom: ... | '[' [testlist [list_iter]] ']' | ...
  list_iter: list_for | list_if
  list_for: 'for' exprlist 'in' testlist [list_iter]
  list_if: 'if' test [list_iter]

Lưu ý rằng trước đây, cú pháp danh sách là '[' [testlist] ']'. Hãy để tôi giải thích nó theo các thuật ngữ khác nhau:

Trình phân tích cú pháp phân tích cú pháp một loạt các biểu thức được phân tách bằng dấu phẩy. Trước đây, nó được kỳ vọng ']'là mã thông báo duy nhất có thể theo sau này. Sau khi thay đổi, 'for'là một mã thông báo sau có thể khác. Điều này hoàn toàn không có vấn đề gì đối với bất kỳ trình phân tích cú pháp nào biết cách phân tích dấu ngoặc đơn phù hợp!

Nếu bạn không muốn hỗ trợ [x, y for ...]vì nó mơ hồ (với người đọc, không phải trình phân tích cú pháp!), Chúng ta có thể thay đổi ngữ pháp thành một cái gì đó như:

'[' test [',' testlist | list_iter] ']'

(Lưu ý rằng |liên kết ít hơn nối và [...]có nghĩa là một phần tùy chọn.)

Cũng xem phản hồi tiếp theo trong chuỗi, nơi Greg Ewing chạy

>>> seq = [1,2,3,4,5]
>>> [x, x*2 for x in seq]
[(1, 2), (2, 4), (3, 6), (4, 8), (5, 10)]

trên một phiên bản đầu của bản vá hiểu danh sách, và nó hoạt động tốt.


-1

Từ Tài liệu :

Như bạn thấy, các bộ dữ liệu đầu ra luôn được đặt trong dấu ngoặc đơn, do đó các bộ dữ liệu lồng nhau được diễn giải chính xác; chúng có thể là đầu vào có hoặc không có dấu ngoặc đơn xung quanh, mặc dù thường thì dấu ngoặc đơn là cần thiết (nếu bộ dữ liệu là một phần của biểu thức lớn hơn). Không thể gán cho các mục riêng lẻ của một tuple, tuy nhiên có thể tạo các bộ dữ liệu có chứa các đối tượng có thể thay đổi, chẳng hạn như danh sách.

Bên trong một danh sách các bộ dữ liệu được lồng trong một danh sách. Vì vậy, chúng phải được đặt trong ngoặc đơn. Nhưng khi không được lồng nhau, ví dụ như the_tuples = 'a','b','c'chúng không cần thiết bởi vì chúng được tự động nhận dạng là bộ dữ liệu.


-2

Python có một số phần tử cú pháp với dấu ngoặc đơn tùy chọn. Trong trường hợp này, đây là:

  • tuple nghĩa đen x, y
  • biểu thức máy phát điện y for x in seq1 for y in seq2

Trong các trường hợp không rõ ràng, chúng có thể được sử dụng mà không cần dấu ngoặc đơn bổ sung:

  • b = x, y
  • sum(y for x in seq1 for y in seq2)

Tuy nhiên, sử dụng cả hai trong cùng một biểu thức là mơ hồ. Dấu ngoặc đơn được yêu cầu để làm rõ nghĩa:

  • [(x, y) for x in seq1 for y in seq2]
  • [x, (y for x in seq1 for y in seq2)]

Theo ngữ pháp Python3, danh sách hiển thị [...]được định nghĩa là chứa hoặc một danh sách biểu ( a, b, *c, d) hoặc một sự hiểu biết ( a for a in b).


1
Biểu thức trình tạo không tồn tại tại thời điểm cú pháp này được giới thiệu.
user2357112 hỗ trợ Monica

@ user2357112supportsMonica Điều đó không thay đổi rằng sự mơ hồ tồn tại ngày nay.
MisterMiyagi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.