2012-01-09 11 views
5

thể trùng lặp:
Is it Pythonic to use list comprehensions for just side effects?Sử dụng một sự hiểu biết như một phím tắt để gọi một phương thức nhiều lần

Đôi khi trong một tập tin kịch bản tôi sẽ viết một cái gì đó giống như [foo(x) for x in (1,2,3)]. Tôi không thực sự quan tâm đến giá trị trả về (nếu có), tôi chỉ thích viết tắt như trái ngược với sử dụng

for x in (1,2,3): 
    foo(x) 

Nhưng trong sự hiểu biết này, tôi đang tạo ra một đối tượng danh sách có mà không thực sự đi bất cứ nơi nào (Tôi đoán nó bị thu gom rác bởi vì không ai giữ một tham chiếu đến nó?)

>>> L = list('SxPyAMz') 
>>> [L.remove(c) for c in ('x', 'y', 'z')] 
[None, None, None] 
>>> print L 
['S', 'P', 'A', 'M'] 

Câu hỏi của tôi: đây là thực tế xấu, hoặc nó hoàn toàn vô hại đối với whiz bởi không được chú ý? Nếu nó xấu, có 1 lớp lót tốt hơn cho các loại phím tắt này không?

Trả lời

3

Tôi có trong quá khứ cũng được coi là thực hành xấu này, và không khuyến khích nó vì chôn vùi logic lặp trong phạm vi hiểu. Nhưng sau đó tôi tìm thấy các công thức consume trong documentation of the itertools module, và ví dụ khẳng định rằng làm looping ở tốc độ C là một số giá trị trong một số trường hợp.

Công thức tiêu thụ sử dụng độ dài 0 độ dài làm đích đến của giá trị throwaway từ việc xử lý lặp lại biểu thức danh sách hiểu/tạo danh sách.

L = list('SxPyAMz') 
deque((L.remove(c) for c in ('x', 'y', 'z')), maxlen=0) 

Bạn có thể làm đẹp này bằng cách định nghĩa một deque 0-chiều dài toàn cầu:

_consumer = deque(maxlen=0) 
do_all = _consumer.extend 

L = list('SxPyAMz') 
do_all(L.remove(c) for c in ('x', 'y', 'z')) 
print L 
6

Nếu bạn không cần phải lưu trữ các kết quả đơn giản đồng bằng "cho" vòng lặp sẽ làm điều đó:

for c in ('x', 'y', 'z'): L.remove(c) 
+1

tôi không thích những vì thiếu xuống dòng và thụt lề là chống lại phong cách python dẫn. – wim

+1

IMHO phiên bản một lớp của cấu trúc điều khiển Python được chấp nhận ở những nơi bạn muốn sử dụng tính năng hiểu danh sách. Ví dụ của bạn có một tên biến hoa là (một lần nữa, IMHO) một vi phạm tồi tệ nhất của PEP8, vì CamelCase nên được dành riêng cho các tên lớp và instances_should_use_underscores. Đơn giản và dễ đọc hơn bất kỳ lựa chọn thay thế nào tôi biết. –

+0

Vâng, nhưng nó chỉ là để trình diễn tại thông dịch viên. Bạn sẽ không nhìn thấy tôi bằng cách sử dụng một danh sách được gọi là L trong mã sản xuất. – wim

7

Vâng, tôi muốn nói đó là một thói quen xấu mà bạn nên tránh vì, như bạn đã được chỉ ra, một đối tượng cơ bản được tạo ra để được thu gom rác sau đó.

Để biết các cách khác để viết biểu thức này, vui lòng xem question này.