Sản phẩm cartesian python không có itertools

Xin chào, tôi đang cố gắng tìm tất cả các hoán vị của một tập hợp độ dài n, trong đó tất cả các phần tử có thể được lặp lại nhiều lần bất kỳ, vì vậy về cơ bản, một tích Descartes của tập hợp n lần, trong đó n là độ dài của hoán vị. Bây giờ tôi biết python itertools. sản phẩm có thể làm điều tương tự một cách dễ dàng nhưng tôi muốn tự mình làm điều đó và tôi đã viết mã này ``` def gen_perm[chars,lenn]. nếu lenn == 1. cho tôi trong ký tự. mang lại cho tôi khác. perms = gen_perm[chars,lenn-1] for i trong perms. cho j trong ký tự. yield i+j ``` Bây giờ tôi không thể nghĩ ra điều gì tốt hơn thế này và tôi cảm thấy điều này không hiệu quả lắm vì tôi phải tính toán tất cả các hoán vị của lần lặp trước i. e. n-1, có cách nào để làm cho nó hiệu quả hơn không và python itertools làm như thế nào?

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 FacebookTwitter để 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ố 8_______

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

Chủ Đề