2010-11-19 32 views
7

điều này có thể được viết bằng một dòng mà không có Liệt kê tổng hợp không?cho-nếu không có danh sách hiểu trong một dòng

for x in vec: 
    if x > 3: 
     ... 
     ... 
+10

Tại sao không?/Tại sao 1 dòng? – kennytm

+0

Tôi không quá quen thuộc với họ, nhưng câu lệnh 'lambda' có phù hợp ở đây không? – Blender

+0

@blender: Chỉ riêng một lambda sẽ là vô nghĩa. Là vị từ cho 'i-/filter', vâng. – delnan

Trả lời

3

Không, bạn không thể. Các Python language reference bang: 'khoản' 'bộ' báo cáo

Compound bao gồm một hoặc hơn Một điều khoản bao gồm một tiêu đề và các khoản tiêu đề của một hợp chất tuyên bố đặc biệt là tất cả cùng một mức thụt đầu dòng. Mỗi tiêu đề khoản bắt đầu bằng cách xác định duy nhất từ khóa và kết thúc bằng dấu hai chấm. Bộ là một nhóm các câu lệnh được kiểm soát bởi một mệnh đề. Một bộ có thể là một hoặc nhiều các câu lệnh đơn lẻ được phân tách bằng dấu chấm phẩy trên cùng dòng với tiêu đề, sau dấu hai chấm của đầu trang hoặc có thể là một hoặc nhiều câu lệnh thụt lề. Chỉ sau dạng của bộ phần mềm mới có thể chứa các câu lệnh phức hợp lồng nhau ; sau đây là bất hợp pháp, chủ yếu là bởi vì nó sẽ không được rõ ràng mà mệnh đề if một sau khoản khác sẽ thuộc về:

if test1: if test2: print x 

Thật vậy, Python tạo ra một SyntaxError cho ifs lồng nhau ở trên. Chính thức hơn về for, đây là ngữ pháp của nó bằng Python:

for_stmt ::= "for" target_list "in" expression_list ":" suite 
       ["else" ":" suite] 

suite   ::= stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT 

stmt_list  ::= simple_stmt (";" simple_stmt)* [";"] 

Lưu ý rằng khi for Tiếp theo là một tuyên bố mà không có một vết lõm, tuyên bố rằng phải là một stmt_list, mà chỉ cho phép simple_stmt trường. simple_stmt là thế này:

simple_stmt ::= expression_stmt 
       | assert_stmt 
       | assignment_stmt 
       | augmented_assignment_stmt 
       | pass_stmt 
       | del_stmt 
       | print_stmt 
       | return_stmt 
       | yield_stmt 
       | raise_stmt 
       | break_stmt 
       | continue_stmt 
       | import_stmt 
       | global_stmt 
       | exec_stmt 

Mà không bao gồm báo cáo hợp chất như iffor.


Điều đó nói rằng, hãy nhớ rằng cú pháp của Python nhằm mục đích rõ ràng. Do đó, tốt hơn là không lồng các câu lệnh như vậy, đây là những gì mà các máy phát/danh sách đã được thực hiện. Nếu bạn cho rằng tính toán của mình đủ đơn giản cho một dòng, thì sự hiểu biết là dành cho bạn. Nếu không, bạn thực sự không muốn làm lộn xộn mã bằng cách có mọi thứ trên một dòng - phá vỡ nó một cách độc đáo với thụt đầu dòng. Một vài dòng phụ không tốn nhiều tiền trong những ngày này.

+1

Tôi không nghĩ rằng anh ta hỏi liệu anh ta có thể đặt 2 câu trên một dòng. Tôi nghĩ anh ta chỉ muốn tác động tổng thể của hai câu lệnh đó xảy ra trên một dòng. – Gerrat

+0

@Eli: Vì anh ta đặt hai dòng dấu chấm lửng trong ví dụ, anh ta có thể làm một cái gì đó theo quy trình với 'x', hiển thị danh sách là một giải pháp không thể chấp nhận được. ** Việc hiểu danh sách không phải là cách để biến bất kỳ vòng lặp nào thành một dòng đơn trực tuyến **. – delnan

+0

@delnan: bạn có thể đúng, tôi thực sự không biết. Không phải là OP-intent-explain một trò chơi SO thú vị? :-) Tôi khuyến khích Roberto để làm rõ những gì anh ta thực sự muốn –

-1

Bạn có thể tưởng tượng somethings như thế này: biểu

def do_something(value): 
    ... 

def do_otherthing(value): 
    ... 


for x in t: do_something(x) if x>3 else do_otherthing(x) 
+0

đó là chính xác những gì ông đã không yêu cầu: "không có List Comprehensions" –

+1

Vui lòng đọc lại câu hỏi. –

+0

Câu hỏi cụ thể không đòi hỏi điều này - bởi vì '...' là một số câu lệnh, trong trường hợp đó, việc hiểu danh sách sẽ không phải là thành ngữ. – delnan

0

Nó có thể, nhưng danh sách comprehensions/máy phát điện là loại chính xác điều mà nên được sử dụng ở đây. Tùy thuộc vào những gì bạn muốn thực hiện trong khối if, bạn có thể sử dụng một số hình thức map hoặc reduce, nhưng việc hiểu danh sách và biểu thức trình tạo có thể là cách tốt nhất để thực hiện.

+0

Tôi cần phải viết vài dòng sau nếu, vì vậy sẽ không bay – Roberto

+0

@Roberto để viết một hàm thực hiện những gì bạn cần và sử dụng trong danh sách hiểu –

+0

thì tôi xóa một dòng cho/nếu mọi lúc tôi phải làm một cái gì đó như thế, nhưng tôi thêm một dòng để khai báo hàm :) – Roberto

0

cho x trong bộ lọc (lambda i: i> 3, vec):

+0

Lưu ý rằng trong Python 2, điều này sẽ lập tức tạo một danh sách mới, thay vì tạo ra các giá trị một cách lười biếng. – delnan

+0

http://docs.python.org/library/itertools.html#itertools.ifilter –

3

Xem @KennyTM ... không có lý do để nén mà nhiều.

Điều gì đang được nói, for x in (i in vec if i > 3) thực hiện công việc, cũng như itertools.ifilter (hoặc chỉ được dựng sẵn filter bằng Python 3) với thuộc tính lambda x: x > 3. Chúng cũng hoạt động với tất cả các lần lặp lại và rất lười (ví dụ: nếu bạn break trong vòng lặp, bạn không kiểm tra một mục quá nhiều).

+0

Toàn bộ điểm, như OP được nêu trong nhận xét, là “nếu * x * là một từ lớn, tôi phải nhập từ đó hai lần ”(thời điểm kéo tóc), vì vậy có lẽ một' filter' + 'lambda' là câu trả lời thích hợp cho câu hỏi này…. – tzot

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