Kể từ Python 2.5, yield <value>
là một biểu thức, không phải là câu lệnh. Xem PEP 342.
Mã rất ghê gớm và không cần thiết xấu xí, nhưng nó là hợp pháp. Thủ thuật trung tâm của nó là sử dụng f((yield x))
bên trong biểu thức trình tạo. Dưới đây là một ví dụ đơn giản về cách làm việc này:
>>> def f(val):
... return "Hi"
>>> x = [1, 2, 3]
>>> list(f((yield a)) for a in x)
[1, 'Hi', 2, 'Hi', 3, 'Hi']
Về cơ bản, sử dụng yield
trong biểu thức máy phát điện gây ra nó để tạo ra hai giá trị cho mọi giá trị trong nguồn iterable. Khi biểu thức máy phát lặp lại qua danh sách các chuỗi, trên mỗi lần lặp lại, trước tiên, yield x
mang lại một chuỗi từ danh sách. Biểu thức đích của genexp là f((yield x))
, vì vậy đối với mọi giá trị trong danh sách, "kết quả" của biểu thức trình tạo là giá trị của f((yield x))
. Nhưng f
chỉ bỏ qua đối số của nó và luôn trả về chuỗi tùy chọn "-o"
. Vì vậy, trên mỗi bước thông qua trình tạo, trước tiên nó tạo ra chuỗi khóa-giá trị (ví dụ: "x=1"
), sau đó "-o"
. Các bên ngoài list(reversed(list(...)))
chỉ cần làm cho một danh sách ra khỏi máy phát điện này và sau đó đảo ngược nó để "-o"
s sẽ đến trước mỗi tùy chọn thay vì sau.
Tuy nhiên, không có lý do nào để thực hiện theo cách này. Có một số lựa chọn thay thế dễ đọc hơn nhiều. Có lẽ rõ ràng nhất chỉ đơn giản là:
kvs = [...] # same list comprehension can be used for this part
result = []
for keyval in kvs:
result.append("-o")
result.append(keyval)
return result
Thậm chí nếu bạn thích ngắn gọn, "thông minh" mã, bạn có thể vẫn chỉ là làm
return sum([["-o", keyval] for keyval in kvs], [])
Danh sách kvs
hiểu chính nó là một sự pha trộn kỳ lạ của khả năng đọc cố gắng và không thể đọc được. Nó được viết đơn giản hơn:
kvs = [str(optName) + separator + str(optValue) for optName, optValue in options.items()]
Bạn nên cân nhắc sắp xếp "can thiệp" cho bất kỳ ai đặt mã này vào trong codebase của bạn.
Dang. Nói về mã không đọc được. – BenDundee
phần hài hước nhất là danh sách (đảo ngược (danh sách ('một phần để có được công tắc' -o', mặc dù – ch3ka
Ngoài ra tất cả các lambdas có thể chỉ là '((lambda _: '-o') ((yield x)) cho x trong kvs) ' –