Câu trả lời nhanh:
Làm list()xung quanh một biểu thức trình tạo (gần như) chính xác tương đương với việc có []dấu ngoặc nhọn xung quanh nó. Vì vậy, vâng, bạn có thể làm
>>> list((x for x in string.letters if x in (y for y in "BigMan on campus")))
Nhưng bạn cũng có thể làm
>>> [x for x in string.letters if x in (y for y in "BigMan on campus")]
Có, điều đó sẽ biến biểu thức trình tạo thành một danh sách dễ hiểu. Đó là điều tương tự và danh sách gọi () trên đó. Vì vậy, cách để tạo một biểu thức trình tạo thành một danh sách là đặt các dấu ngoặc nhọn xung quanh nó.
Giải thích chi tiết:
Biểu thức trình tạo là một biểu thức "trần trụi" for. Như vậy:
x*x for x in range(10)
Bây giờ, bạn không thể tự dán nó vào một dòng, bạn sẽ gặp lỗi cú pháp. Nhưng bạn có thể đặt dấu ngoặc đơn xung quanh nó.
>>> (x*x for x in range(10))
<generator object <genexpr> at 0xb7485464>
Điều này đôi khi được gọi là hiểu trình tạo, mặc dù tôi nghĩ tên chính thức vẫn là biểu thức trình tạo, thực sự không có bất kỳ sự khác biệt nào, dấu ngoặc đơn chỉ ở đó để làm cho cú pháp hợp lệ. Bạn không cần chúng nếu bạn đang chuyển nó vào làm tham số duy nhất cho một hàm, ví dụ:
>>> sorted(x*x for x in range(10))
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Về cơ bản tất cả các cách hiểu khác có sẵn trong Python 3 và Python 2.7 chỉ là đường cú pháp xung quanh một biểu thức trình tạo. Đặt hiểu biết:
>>> {x*x for x in range(10)}
{0, 1, 4, 81, 64, 9, 16, 49, 25, 36}
>>> set(x*x for x in range(10))
{0, 1, 4, 81, 64, 9, 16, 49, 25, 36}
Đọc hiểu chính tả:
>>> dict((x, x*x) for x in range(10))
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
>>> {x: x*x for x in range(10)}
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
Và liệt kê các kiến thức hiểu trong Python 3:
>>> list(x*x for x in range(10))
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> [x*x for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Trong Python 2, khả năng hiểu danh sách không chỉ là đường cú pháp. Nhưng sự khác biệt duy nhất là x sẽ bị rò rỉ trong Python 2 vào không gian tên.
>>> x
9
Trong khi sử dụng Python 3, bạn sẽ nhận được
>>> x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
Điều này có nghĩa là cách tốt nhất để có được một bản in đẹp về nội dung của biểu thức trình tạo của bạn bằng Python là tạo một danh sách dễ hiểu từ nó! Tuy nhiên, điều này rõ ràng sẽ không hoạt động nếu bạn đã có một đối tượng máy phát điện. Làm điều đó sẽ chỉ tạo danh sách một trình tạo:
>>> foo = (x*x for x in range(10))
>>> [foo]
[<generator object <genexpr> at 0xb7559504>]
Trong trường hợp đó, bạn sẽ cần gọi list():
>>> list(foo)
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Mặc dù điều này hoạt động, nhưng hơi ngu ngốc:
>>> [x for x in foo]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]