2010-06-01 14 views
142

Đây là mã tôi đã cố gắng để trở thành một sự hiểu biết danh sách:Có thể sử dụng 'else' trong một danh sách python comprehension không?

table = '' 
for index in xrange(256): 
    if index in ords_to_keep: 
     table += chr(index) 
    else: 
     table += replace_with 

Có một cách để thêm các tuyên bố khác để hiểu điều này?

table = ''.join(chr(index) for index in xrange(15) if index in ords_to_keep) 

Trả lời

229

Cú pháp a if b else c là một nhà điều hành ternary bằng Python mà đánh giá để a nếu điều kiện b là đúng - nếu không, nó đánh giá để c . Nó có thể được sử dụng trong báo cáo hiểu:

>>> [a if a else 2 for a in [0,1,0,3]] 
[2, 1, 2, 3] 

Vì vậy, ví dụ của bạn,

table = ''.join(chr(index) if index in ords_to_keep else replace_with 
       for index in xrange(15)) 
+9

Lưu ý rằng điều này chỉ hoạt động trong Python 2.5 và sau này. –

+3

tuyệt vời! Rất hữu ích. – professorDante

+6

Cũng lưu ý rằng 'else' là cần thiết và không thể được ommited, bởi vì một giá trị kết quả là luôn luôn cần thiết. – sebix

14

Nếu bạn muốn else bạn không muốn lọc danh sách hiểu, bạn muốn nó lặp lại trên mọi giá trị. Bạn có thể sử dụng true-value if cond else false-value như báo cáo kết quả thay vào đó, và loại bỏ các bộ lọc từ cuối cùng:

table = ''.join(chr(index) if index in ords_to_keep else replace_with for index in xrange(15)) 
1

Ngoài ra, tôi sẽ là ngay trong kết luận rằng một danh sách hiểu là cách hiệu quả nhất để làm điều này?

Có thể. Việc hiểu danh sách vốn không hiệu quả về mặt tính toán. Nó vẫn đang chạy trong thời gian tuyến tính.

Từ kinh nghiệm cá nhân của tôi: Tôi đã giảm đáng kể thời gian tính toán khi xử lý các tập dữ liệu lớn bằng cách thay thế tính năng liệt kê danh sách (đặc biệt là lồng nhau) với cấu trúc kiểu vòng lặp/danh sách nối tiếp bạn có ở trên. Trong ứng dụng này tôi nghi ngờ bạn sẽ nhận thấy một sự khác biệt.

+1

woops, tôi có nghĩa là để hỏi về phương pháp tham gia vs = trên một chuỗi. – Josh

+0

Thú vị. Điều này (http://wiki.python.org/moin/PythonSpeed#Takeadvantageofinterpreteroptimizations) nói cách khác. – kennytm

+0

@Josh: trong phiên bản cũ của Python, phương thức join() là rất cao. Phiên bản mới hơn của trình thông dịch cố gắng tối ưu hóa phương pháp + =, nhưng tôi không chắc chắn cách thức hoạt động của nó tốt. Tôi hầu như luôn luôn chỉ sử dụng phương thức join(). –

6

Để sử dụng else trong việc hiểu danh sách trong lập trình python, bạn có thể thử đoạn mã bên dưới. Điều này sẽ giải quyết vấn đề của bạn, đoạn mã được thử nghiệm trên python 2.7 và python 3.5.

obj = ["Even" if i%2==0 else "Odd" for i in range(10)] 
0

Câu trả lời hay, nhưng chỉ muốn đề cập đến một từ khóa "pass" sẽ không hoạt động trong phần if/else của danh sách hiểu (như được đăng trong các ví dụ được đề cập ở trên).

#works 
list1 = [10, 20, 30, 40, 50] 
newlist2 = [x if x > 30 else x**2 for x in list1 ] 
print(newlist2, type(newlist2)) 

#but this WONT work 
list1 = [10, 20, 30, 40, 50] 
newlist2 = [x if x > 30 else pass for x in list1 ] 
print(newlist2, type(newlist2)) 

Điều này đã được thử và thử nghiệm trên trăn 3.4. Lỗi như sau:

newlist2 = [x if x > 30 else pass for x in list1 ]          
SyntaxError: invalid syntax 

Vì vậy, cố gắng tránh pass-es trong comprehensions danh sách

+0

Cấu trúc if/else chỉ là một biểu thức cho đến khi hiểu được danh sách. Nếu bạn muốn để lại các mục, bạn cần phải đặt biểu thức của bạn thay cho 'expr2' ở đây' [expr1 cho x trong list1 nếu expr2] ' –

+0

Làm tốt công việc trong một khối bình thường nếu khối khác, với tôi, điều đó ngụ ý rằng nó cũng sẽ hoạt động ở mọi nơi. Nhưng không phải như vậy trong danh sách comprehensions. – Plankton

+1

Nhưng đây không phải là khối bình thường nếu/else. Đó là [một biểu thức] (https://docs.python.org/3/faq/programming.html#is-there-an-equivalent-of-c-s-ternary-operator). Bạn không thể sử dụng elif trong đó. –

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