2015-10-17 17 views
6

Chương trình dưới đây [Python 3.4] là một Eratosthenes sàng đơn giản:Máy tạo Python; hai chương trình dường như giống hệt nhau làm việc khác nhau

from itertools import * 
def excl(ns,pr): 
    return (i for i in ns if i%pr) 
def sieve(ns): 
    while True: 
     pr=next(ns) 
     yield pr 
     ns=excl(ns,pr) 
     # ns=(i for i in ns if i%pr) 
r=list(islice(sieve(count(2)),10)) 

trong đó sản xuất [2, 3, 5, 7, 11, Điều 13, 17, 19, 23, 29 ]. ĐƯỢC. Bỏ ghi chú dòng inlines excl() và nhận xét cuộc gọi, cho [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]. Tại sao?

Có liên quan đến các sự cố xảy ra khi modyfing một chuỗi bên trong một vòng lặp lặp qua nó?

Cảm ơn bạn đã gợi ý.

Trả lời

2

Vấn đề của bạn là pr gọi bằng khái niệm máy phát điện là cùng pr mà bạn sửa đổi trong phiên bản kế tiếp của vòng lặp while của bạn, vì vậy mỗi số đó không phải là chia hết cho số 'thủ' trước được xử lý là 'nguyên tố'. Mà chính nó sửa đổi pr và như vậy. Trong các chức năng excl, các pr mà bạn đề cập đến là một trong những thông qua như một đối số, mà không bao giờ thay đổi.

+0

Tôi không chắc chắn rằng tôi hiểu câu trả lời này. Pr nguyên tố không thay đổi trong excl (cũng không phải trong gen.expression), nó thay đổi trong vòng lặp, và bối cảnh này là giống hệt nhau cho phiên bản nội tuyến và 'gọi'. BTW Tôi đã xóa một nhận xét sai về bộ lọc(). –

+0

@JerzyKarczmarczuk Theo [PEP 227] (https://www.python.org/dev/peps/pep-0227/), nếu tên được sử dụng trong một khối mã (hàm lồng nhau), nhưng nó không bị ràng buộc ở đó và không được khai báo chung, việc sử dụng được xử lý ** như một tham chiếu đến ** vùng chức năng kèm theo gần nhất. Vì nó áp dụng cho trường hợp của bạn, biểu thức máy phát là một hàm dưới mui xe, và nó không định nghĩa biến 'pr', do đó,' pr' là tham chiếu ** ** với 'pr' trong hàm kèm theo ('sieve'). Điều đó có nghĩa là khi 'pr' trong' sieve' thay đổi, thì 'pr' trong biểu thức trình tạo. – ppperry

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