Viết chương trình Python để tạo các tổ hợp không lặp lại của tích Descartes gồm bốn danh sách các số đã cho
Giải pháp mẫu
Mã Python
import itertools as it
mums1 = [1, 2, 3, 4]
mums2 = [5, 6, 7, 8]
mums3 = [9, 10, 11, 12]
mums4 = [13, 14, 15, 16]
print["Original lists:"]
print[mums1]
print[mums2]
print[mums3]
print[mums4]
print["\nSum of the specified range:"]
for i in it.product[[tuple[mums1]], it.permutations[mums2], it.permutations[mums3], it.permutations[mums4]]:
print[i]
Đầu ra mẫu
Original lists: [1, 2, 3, 4] [5, 6, 7, 8] [9, 10, 11, 12] [13, 14, 15, 16] Sum of the specified range: [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]] [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 16, 15]]
Trình chỉnh sửa mã Python
Có một cách khác để giải quyết giải pháp này?
Trước. Viết chương trình Python để xen kẽ nhiều danh sách có cùng độ dài. Sử dụng mô-đun itertools
Kế tiếp. Viết chương trình Python để đếm tần suất của các phần tử trùng lặp liên tiếp trong một danh sách các số đã cho. Sử dụng mô-đun itertools
Mức độ khó của bài tập này là gì?
Dễ dàng trung bình khóKiểm tra kỹ năng Lập trình của bạn với bài kiểm tra của w3resource
Theo dõi chúng tôi trên Facebook và Twitter để cập nhật thông tin mới nhất.
con trăn. Lời khuyên trong ngày
thời gian nó
thư viện timeit rất phù hợp để định thời gian thực thi Python. Chỉ cần chuyển một hàm ở định dạng chuỗi sang timeit. timeit[] và nó sẽ thực hiện 1 triệu lần thực thi để báo cáo thời gian tối thiểu mà mã cần
Nó rất hữu ích để so sánh các đoạn mã nhỏ và các chức năng khác nhau nhưng có thể chậm chạp với mã lớn
Hãy xem ví dụ bên dưới minh họa sự khác biệt về thời gian thực hiện giữa 2 phương thức hiểu danh sách rất giống nhau trong Python
Hàm tính tích Descartes của một tập hợp các lần lặp. Tuy nhiên, việc triển khai hoạt động bằng cách tiêu thụ hoàn toàn các lần lặp đầu vào và giữ các nhóm giá trị trong bộ nhớ để tạo ra các sản phẩm. Tài liệu lưu ý điều đó có nghĩa là “nó chỉ hữu ích với đầu vào hữu hạn” nhưng trong thực tế, các lần lặp này cũng phải đủ nhỏ để chuyển đổi thành bộ dữ liệu. Điều này có thể dẫn đến một loạt các vấn đề bao gồm
>>> from itertools import product
>>> next[product[range[1 >> next[product[range[1 >> from itertools import count
>>> next[product[count[], count[]]
# Hangs
Tôi muốn đề xuất thêm một biến thể của chức năng sản phẩm vào thư viện itertools có thể xử lý các trường hợp như vậy, tuy nhiên tôi nghi ngờ rằng rất có thể đây cần phải là một chức năng riêng biệt. Như một ví dụ cụ thể để xem xét, tôi sẽ đề xuất cách triển khai sau đây, lần lượt lấy một mục từ mỗi lần lặp và tạo ra tất cả các bộ dữ liệu có thể được hình thành từ nó và tất cả các mục trước đó đã được nhìn thấy trước khi thêm nó vào kho lưu trữ các mục
from itertools import cycle, product, tee
def iproduct[*iterables, repeat=1]:
iterables = [item for row in zip[*[tee[iterable, repeat] for iterable in iterables]] for item in row]
N = len[iterables]
saved = [[] for _ in range[N]] # All the items that we have seen of each iterable.
exhausted = set[] # The set of indices of iterables that have been exhausted.
for i in cycle[range[N]]:
if i in exhausted: # Just to avoid repeatedly hitting that exception.
continue
try:
item = next[iterables[i]]
yield from product[*saved[:i], [item], *saved[i+1:]] # Finite product.
saved[i].append[item]
except StopIteration:
exhausted.add[i]
if not saved[i] or len[exhausted] == N: # Product is empty or all iterables exhausted.
return
yield [] # There are no iterables.
Điều này xử lý một loạt các trường hợp khác nhau nhưng quan trọng là nó tạo ra các cặp giống như itertools.product
[tùy thuộc vào đơn đặt hàng]
>>> from itertools import islice, product
>>> X = [i+1 for i in range[20]]
>>> Y = [2*i for i in range[5]]
>>> print[*islice[iproduct[X, Y], 10]]
[1, 0] [2, 0] [1, 2] [2, 2] [3, 0] [3, 2] [1, 4] [2, 4] [3, 4] [4, 0]
>>> print[sorted[iproduct[X, Y]] == sorted[product[X, Y]]]
True
Nhưng vì nó không bắt đầu bằng cách xây dựng các bộ dữ liệu đầu vào nên nó có thể xử lý các lần lặp rất lớn
>>> X = [i + 7 for i in range[2 >> Y = [i for i in range[10**10]]
>>> print[*islice[iproduct[X, Y], 10]]
[9, 0] [27, 0] [9, 1] [27, 1] [28, 0] [28, 1] [9, 2] [27, 2] [28, 2] [29, 0]
Điều này cũng có nghĩa là nó cũng xử lý các lần lặp vô hạn hoàn toàn tốt
>>> from itertools import count
>>> X = [i for i in range[20]]
>>> Y = count[]
>>> print[*islice[iproduct[X, Y], 10]]
[0, 0] [1, 0] [0, 1] [1, 1] [2, 0] [2, 1] [0, 2] [1, 2] [2, 2] [3, 0]
>>> X = count[]
>>> Y = count[]
>>> print[*islice[iproduct[X, Y], 10]]
[0, 0] [1, 0] [0, 1] [1, 1] [2, 0] [2, 1] [0, 2] [1, 2] [2, 2] [3, 0]
Các lần lặp trống dẫn đến một sản phẩm trống và không có lần lặp nào dẫn đến bộ dữ liệu trống
>>> X = [i for i in range[0]]
>>> Y = count[]
>>> next[iproduct[X, Y]]
StopIteration
>>> print[*iproduct[]]
[]
>>> X = count[]
>>> print[*iproduct[X, repeat=0]]
[]
Và đã lặp lại hoạt động như itertools.product[..., repeat=...]
Sự khác biệt đáng chú ý duy nhất giữa cái này và itertools.product
là các bộ dữ liệu được tạo ra theo một thứ tự khác. Vì vậy, trong khi itertools.product
tạo các cặp của nó sao cho nếu các bộ lặp của đầu vào được sắp xếp thì các bộ sản phẩm được phát ra theo thứ tự được sắp xếp [thứ tự từ điển], nếu các bộ lặp đầu vào của
from itertools import cycle, product, tee
def iproduct[*iterables, repeat=1]:
iterables = [item for row in zip[*[tee[iterable, repeat] for iterable in iterables]] for item in row]
N = len[iterables]
saved = [[] for _ in range[N]] # All the items that we have seen of each iterable.
exhausted = set[] # The set of indices of iterables that have been exhausted.
for i in cycle[range[N]]:
if i in exhausted: # Just to avoid repeatedly hitting that exception.
continue
try:
item = next[iterables[i]]
yield from product[*saved[:i], [item], *saved[i+1:]] # Finite product.
saved[i].append[item]
except StopIteration:
exhausted.add[i]
if not saved[i] or len[exhausted] == N: # Product is empty or all iterables exhausted.
return
yield [] # There are no iterables.
2 được sắp xếp thì nó tạo ra các bộ của nó được sắp xếp theo thứ tự sau>>> def grade[x]:
>>> m = max[x]
>>> return [m, [i for i, y in enumerate[x] if y == m][-1], x]
>>> X = range[5]
>>> Y = range[10]
>>> print[list[iproduct[X, Y]] == sorted[product[X, Y], key=grade]]
True
Do sự khác biệt này, tôi không nghĩ rằng việc thay thế itertools.product
để thay thế cho
from itertools import cycle, product, tee
def iproduct[*iterables, repeat=1]:
iterables = [item for row in zip[*[tee[iterable, repeat] for iterable in iterables]] for item in row]
N = len[iterables]
saved = [[] for _ in range[N]] # All the items that we have seen of each iterable.
exhausted = set[] # The set of indices of iterables that have been exhausted.
for i in cycle[range[N]]:
if i in exhausted: # Just to avoid repeatedly hitting that exception.
continue
try:
item = next[iterables[i]]
yield from product[*saved[:i], [item], *saved[i+1:]] # Finite product.
saved[i].append[item]
except StopIteration:
exhausted.add[i]
if not saved[i] or len[exhausted] == N: # Product is empty or all iterables exhausted.
return
yield [] # There are no iterables.
2 là phù hợp nhưng điều này có thể được đưa vào như một chức năng riêng biệt