2010-03-23 13 views
30

Giả sử tôi có một danh sách mà tôi không muốn trả lại nhưng để mang lại giá trị từ. Cách nhiệt tình nhất để làm điều đó là gì?Làm thế nào để thu được tất cả các giá trị từ một danh sách theo cách thủ công?

Đây là ý của tôi. Nhờ một số tính toán không lười biếng tôi đã tính toán danh sách ['a', 'b', 'c', 'd'], nhưng mã của tôi thông qua dự án sử dụng tính toán lười biếng, vì vậy tôi muốn mang lại giá trị từ hàm của tôi thay vì trả về toàn bộ danh sách.

Tôi hiện đã viết nó như sau:

my_list = ['a', 'b', 'c', 'd'] 
for item in my_list: 
    yield item 

Nhưng điều này không cảm thấy pythonic với tôi.

+3

Tại sao bạn cần làm điều đó, bạn có thể sử dụng "cho x trong vùng chứa" nơi vùng chứa là danh sách hoặc vùng chứa là một trình lặp ... cú pháp không thay đổi bất kể loại, vậy tại sao nó lại quan trọng cho dù đó là danh sách hoặc một iterator? Bạn vẫn sẽ phải treo vào danh sách để thu được từ nó, vì vậy chỉ đơn giản là đi qua xung quanh danh sách. –

+0

Nhận xét bên: với "Danh sách", nhiều người sẽ nghĩ về nó như một tên lớp vì chữ hoa hàng đầu (xem PEP 8). Bạn có thể sử dụng "list_" hoặc "my_list", v.v. – EOL

+0

EOL, tôi đánh giá cao nhận xét của bạn. Cảm ơn. – bodacydo

Trả lời

28

Sử dụng iter để tạo ra một danh sách iterator ví dụ

return iter(List) 

mặc dù nếu bạn đã có danh sách, bạn chỉ có thể trả lại, điều này sẽ hiệu quả hơn.

+0

Câu hỏi hay. Và tôi không có câu trả lời. Tôi sẽ trả lại toàn bộ danh sách. Tôi chỉ nghĩ rằng trả lại một máy phát điện là một ý tưởng tốt bởi vì tất cả mọi thứ trong dự án sử dụng máy phát điện (ngoại trừ nơi này - tôi nhận được danh sách này từ một thư viện mà không phải là lười biếng). – bodacydo

+3

Đây là quá mức cần thiết khi lệnh gọi tới 'lặp' là hoàn toàn dư thừa. – msw

+2

'iter' là một quá mức cần thiết nhưng nó không hoàn toàn dư thừa, nó có thể được sử dụng để nhớ bạn đang ở đâu trong khi lặp qua danh sách và bạn có thể truyền nó cùng với danh sách bạn sẽ phải vượt qua một chỉ mục quá –

1

Bạn có thể xây dựng một máy phát điện bằng cách nói

(x for x in List) 
+0

Vì vậy, tôi có thể làm 'return (x cho x trong danh sách)'? – bodacydo

+1

Có. Nhưng tôi không nghĩ rằng nó sẽ giúp bạn tiết kiệm nhiều công sức, vì bạn đã tính toán toàn bộ danh sách, vậy tại sao không trả lại? –

+6

Việc xây dựng trong iter() làm điều này cho bạn: không có nhu cầu cho một biểu thức máy phát điện, mà cũng có những bất lợi của được chậm hơn. – EOL

34

Vì câu hỏi này không chỉ định; Tôi sẽ cung cấp câu trả lời áp dụng trong Python >= 3.3

Nếu bạn chỉ cần trả lại danh sách đó, hãy làm như Anurag suggests, nhưng nếu vì lý do nào đó chức năng được đề cập thực sự cần phải là máy phát, bạn có thể ủy quyền cho một trình tạo khác; giả sử bạn muốn hậu tố danh sách kết quả, nhưng chỉ khi danh sách này bị cạn kiệt đầu tiên.

def foo(): 
    list_ = ['a', 'b', 'c', 'd'] 
    yield from list_ 

    if something: 
     yield this 
     yield that 
     yield something_else 

Trong các phiên bản trăn trước 3.3, bạn không thể sử dụng cú pháp này; bạn sẽ phải sử dụng mã như trong câu hỏi, với vòng lặp for và câu lệnh yield đơn trong cơ thể.

Cách khác; bạn có thể quấn máy phát điện trong một chức năng thường xuyên và trả lại kết quả chain ed: Điều này cũng có lợi thế là làm việc trong python 2 và 3

from itertools import chain 

def foo(): 
    list_ = ['a', 'b', 'c', 'd'] 

    def _foo_suffix(): 
     if something: 
      yield this 
      yield that 
      yield something_else 

    return chain(list_, _foo_suffix()) 
+14

Tính năng 'yield from list_' là một cú pháp đẹp, và là những gì tôi đến đây để tìm kiếm. Tôi không thể sử dụng nó trong 2.7. –

0

nhất Pythonically cách để làm nhiệm vụ này là

In [1]: my_list = ['a', 'b', 'c', 'd'] 

In [2]: (x for x in my_list) 
Out[2]: <generator object <genexpr> at 0x7fd9e4fdc230>