2010-03-08 44 views
8

Có thể liệt kê danh sách một cách lười biếng trong Python không?Python, danh sách lười biếng

Ví dụ

a = 1 
list = [a] 
print list 
#[1] 
a = 2 
print list 
#[1] 

Nếu danh sách đã được thiết lập để đánh giá một cách lười biếng thì dòng cuối cùng sẽ là [2]

+0

Đây không phải là những gì tôi đã hiểu được đánh giá lười biếng. Tôi muốn nói rằng nó giống như thế này: chúng tôi muốn tìm 30 số dương đầu tiên mà hình vuông chia hết cho 3. Với ngôn ngữ háo hức, bạn viết mã cho hiệu suất - 'while (list.length <30) if (i * i % 3 == 0) list + = i ++; 'hoặc biểu cảm (nhưng bỏ đi các danh sách không cần thiết lớn trên đường đi) -' list1 = range 0..10000; cho i trong list1 nếu i * i% 3 == 0 list2.add i; list2.trim (30) '.Với lười biếng bạn viết một cái gì đó giống như sau này, nhưng có được hiệu suất của cựu. Daniel Tao [giải thích nó rực rỡ] (http://danieltao.com/lazy.js/). –

+0

Một cách lười biếng có thể trông như thế này: 'range(). Filter (var trong đó var * var% 3 == 0) .take (30)' - nó được viết rất rõ ràng, nhưng mã không chạy một cách bất hợp pháp. Nó chạy: 'range' sinh ra 1.' Filter' - không thành công vì '1 * 1% 3! = 0'. Sau đó 'dải ô' tạo ra 2.' Bộ lọc' không thành công. Sau đó 'dải ô' tạo ra 3.' Lọc' đi bởi vì '3 * 3% 3 == 0'. 'Take' xếp hàng nó như một câu trả lời. Sau khi 'take' đã lấy 30, thuật toán dừng lại. Nó chỉ sử dụng nhiều bộ nhớ như nó cần, nhưng nó cũng rất dễ đọc (và song song) mã. –

Trả lời

10

Khái niệm đánh giá "lười" thường đi kèm với các ngôn ngữ chức năng - nhưng trong những thứ bạn không thể gán lại hai giá trị khác nhau cho cùng một số nhận dạng, vì vậy, thậm chí không thể sao chép ví dụ của bạn.

Điểm không phải là về sự lười biếng chút nào - nó là sử dụng một định danh được đảm bảo để được giống hệt nhau để nhận được một tham chiếu đến cùng một giá trị định danh được tham khảo, và tái gán một định danh, một trần tên, với một giá trị khác, được đảm bảo để làm cho số nhận dạng tham chiếu đến một giá trị khác từ chúng. Tham chiếu đến giá trị đầu tiên (đối tượng) không bị mất.

Hãy xem xét một ví dụ tương tự khi gán lại cho tên trống không được phát, nhưng thay vì bất kỳ loại đột biến nào khác (đối với một đối tượng có thể thay đổi, tất nhiên - số và chuỗi không thay đổi), bao gồm gán khác hơn một tên trọc:

>>> a = [1] 
>>> list = [a] 
>>> print list 
[[1]] 
>>> a[:] = [2] 
>>> print list 
[[2]] 

vì không có a - ... rằng reassigns tên trọc a, mà đúng hơn là một a[:] = ... rằng reassigns a 's nội dung, nó trivially dễ dàng để làm Python là 'lười biếng' như bạn muốn (và thực sự nó sẽ mất tôi nỗ lực để làm cho nó "háo hức"!) ... nếu lười biếng vs háo hức có bất cứ điều gì để làm với một trong những trường hợp này (mà nó không ;-).

Chỉ cần lưu ý đến ngữ nghĩa hoàn toàn đơn giản của "gán cho một tên trống" (và gán cho bất kỳ thứ gì khác, có thể được tinh chỉnh và điều khiển bằng cách sử dụng các loại của riêng bạn một cách thích hợp) và ảo ảnh quang học háo hức "có thể hy vọng biến mất ;-)

6

Python là not really very lazy in general.

Bạn có thể sử dụng máy phát để mô phỏng cấu trúc dữ liệu lười (như danh sách vô hạn, vân vân), nhưng như những thứ như sử dụng cú pháp danh sách bình thường, vâng, bạn sẽ không có sự lười biếng.

1

Đã qua bài đăng này khi tìm kiếm danh sách thực hiện lười biếng thực sự, nhưng nó có vẻ giống như một điều thú vị để thử và làm việc.

Việc thực hiện sau đây không cơ bản những gì ban đầu được hỏi cho:

from collections import Sequence 

class LazyClosureSequence(Sequence): 
    def __init__(self, get_items): 
     self._get_items = get_items 

    def __getitem__(self, i): 
     return self._get_items()[i] 

    def __len__(self): 
     return len(self._get_items()) 

    def __repr__(self): 
     return repr(self._get_items()) 

Bạn sử dụng nó như thế này:

>>> a = 1 
>>> l = LazyClosureSequence(lambda: [a]) 
>>> print l 
[1] 
>>> a = 2 
>>> print l 
[2] 

này rõ ràng là khủng khiếp.

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