next(i for i in itertools.imap(lambda x: random.randint(p,q)|1,itertools.count()) if isPrime(i))
Điều này bắt đầu bằng itertools.count() - điều này mang lại một tập hợp vô hạn.
Mỗi số được ánh xạ tới một số ngẫu nhiên mới trong phạm vi, bởi itertools.imap(). imap giống như bản đồ, nhưng trả về một trình lặp, thay vì một danh sách - chúng ta không muốn tạo ra một danh sách các số ngẫu nhiên vô hạn!
Sau đó, tìm thấy số phù hợp đầu tiên và trả về.
Hoạt động hiệu quả, ngay cả khi p và q cách nhau rất xa - ví dụ: 1 và 10 ** 30, tạo danh sách đầy đủ sẽ không hoạt động!
Nhân tiện, điều này không hiệu quả hơn mã của bạn ở trên và khó hiểu hơn rất nhiều - vui lòng xem xét lập trình viên tiếp theo để đọc mã của bạn và chỉ cần làm như bạn đã làm ở trên. Lập trình viên đó có thể là bạn trong sáu tháng, khi bạn quên mã này được cho là phải làm gì!
P.S - trong thực tế, bạn có thể muốn thay thế count() bằng xrange (KHÔNG phạm vi!), Ví dụ: xrange((p-q)**1.5+20)
không được nhiều hơn số lần thử (cân bằng giữa các thử nghiệm giới hạn cho phạm vi nhỏ và phạm vi rộng và không có hơn 1/2% cơ hội thất bại nếu thành công), nếu không, như được đề xuất trong một bài đăng khác, bạn có thể lặp lại mãi mãi.
PPS - cải thiện: thay thế random.randint(p,q)
với random.randint(p,q)|1
- điều này làm cho mã gấp đôi hiệu quả, nhưng loại trừ khả năng rằng kết quả sẽ là 2.
Nguồn
2015-01-08 01:17:56
Có vẻ như sẽ tốt hơn khi tạo danh sách các số nguyên tố giữa 'p' và' q' và sau đó chọn một số ngẫu nhiên từ danh sách đó. –
Bạn có thể tăng khả năng số nguyên tố bằng cách đặt bit thấp nhất thành 1, do đó làm cho nó trở thành số lẻ - chỉ có một số nguyên tố, tức là 2. Trên thực tế, tất cả các số nguyên tố không phải là 2 và 3 đều dưới đây hoặc một trên bội số của sáu. –
Tôi ghét khi ai đó downvote một câu hỏi mà không nói lý do tại sao vì OP không thể sửa chữa nó nếu anh ta không biết những gì là sai. –