Hướng dẫn python cartesian product of two lists - sản phẩm cartesian python của hai danh sách

Cho Python 2.5 trở lên:

>>> [(a, b, c) for a in [1,2,3] for b in ['a','b'] for c in [4,5]]
[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), 
 (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5), 
 (3, 'b', 4), (3, 'b', 5)]

Đây là phiên bản đệ quy của

>>> list(product([1,2,3], ['a','b'], [4,5])) 
[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), 
 (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5), 
 (3, 'b', 4), (3, 'b', 5)]
>>> list(product([1,2,3]))
[(1,), (2,), (3,)]
>>> list(product([]))
[]
>>> list(product())
[()]
0 (chỉ là một minh họa):

def product(*args):
    if not args:
        return iter(((),)) # yield tuple()
    return (items + (item,) 
            for items in product(*args[:-1]) for item in args[-1])

Example:

>>> list(product([1,2,3], ['a','b'], [4,5])) 
[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), 
 (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5), 
 (3, 'b', 4), (3, 'b', 5)]
>>> list(product([1,2,3]))
[(1,), (2,), (3,)]
>>> list(product([]))
[]
>>> list(product())
[()]

Sử dụng

>>> list(product([1,2,3], ['a','b'], [4,5])) 
[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), 
 (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5), 
 (3, 'b', 4), (3, 'b', 5)]
>>> list(product([1,2,3]))
[(1,), (2,), (3,)]
>>> list(product([]))
[]
>>> list(product())
[()]
1 để tạo sản phẩm Cartesian của nhiều danh sách trong Python.

  • itertools.product () - Các chức năng tạo trình lặp lại cho vòng lặp hiệu quả - Tài liệu Python 3.9.1

Bài viết này mô tả các nội dung sau đây.

  • Sản phẩm Cartesian là gì
  • Sử dụng cơ bản của
    >>> list(product([1,2,3], ['a','b'], [4,5])) 
    [(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), 
     (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5), 
     (3, 'b', 4), (3, 'b', 5)]
    >>> list(product([1,2,3]))
    [(1,), (2,), (3,)]
    >>> list(product([]))
    []
    >>> list(product())
    [()]
    
    1
  • Sử dụng cùng một danh sách (có thể lặp lại) nhiều lần:
    >>> list(product([1,2,3], ['a','b'], [4,5])) 
    [(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), 
     (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5), 
     (3, 'b', 4), (3, 'b', 5)]
    >>> list(product([1,2,3]))
    [(1,), (2,), (3,)]
    >>> list(product([]))
    []
    >>> list(product())
    [()]
    
    3
  • So sánh tốc độ với nhiều vòng (các vòng lồng nhau)

Sản phẩm Cartesian là gì

Sử dụng cơ bản của

>>> list(product([1,2,3], ['a','b'], [4,5])) 
[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), 
 (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5), 
 (3, 'b', 4), (3, 'b', 5)]
>>> list(product([1,2,3]))
[(1,), (2,), (3,)]
>>> list(product([]))
[]
>>> list(product())
[()]
1

  • Sử dụng cùng một danh sách (có thể lặp lại) nhiều lần:
    >>> list(product([1,2,3], ['a','b'], [4,5])) 
    [(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), 
     (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5), 
     (3, 'b', 4), (3, 'b', 5)]
    >>> list(product([1,2,3]))
    [(1,), (2,), (3,)]
    >>> list(product([]))
    []
    >>> list(product())
    [()]
    
    3

Sản phẩm của Cartesian là tập hợp tất cả các kết hợp các yếu tố từ nhiều bộ.

Sản phẩm Cartesian - Wikipedia

  • Các ví dụ cụ thể được hiển thị dưới đây.

Nhập mô -đun

>>> list(product([1,2,3], ['a','b'], [4,5])) 
[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), 
 (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5), 
 (3, 'b', 4), (3, 'b', 5)]
>>> list(product([1,2,3]))
[(1,), (2,), (3,)]
>>> list(product([]))
[]
>>> list(product())
[()]
4. Nó được bao gồm trong thư viện tiêu chuẩn, do đó, không cần cài đặt bổ sung .________ 25 được sử dụng để làm cho kết quả dễ đọc hơn.

import itertools
import pprint

l1 = ['a', 'b', 'c']
l2 = ['X', 'Y', 'Z']

p = itertools.product(l1, l2)

print(p)
# 

print(type(p))
# 

Bản in đẹp với pprint trong Python

for v in p:
    print(v)
# ('a', 'X')
# ('a', 'Y')
# ('a', 'Z')
# ('b', 'X')
# ('b', 'Y')
# ('b', 'Z')
# ('c', 'X')
# ('c', 'Y')
# ('c', 'Z')

for v in p:
    print(v)

Vượt qua hai danh sách như là đối số.

>>> list(product([1,2,3], ['a','b'], [4,5])) 
[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), 
 (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5), 
 (3, 'b', 4), (3, 'b', 5)]
>>> list(product([1,2,3]))
[(1,), (2,), (3,)]
>>> list(product([]))
[]
>>> list(product())
[()]
1 Trả về một đối tượng loại
>>> list(product([1,2,3], ['a','b'], [4,5])) 
[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), 
 (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5), 
 (3, 'b', 4), (3, 'b', 5)]
>>> list(product([1,2,3]))
[(1,), (2,), (3,)]
>>> list(product([]))
[]
>>> list(product())
[()]
7.
>>> list(product([1,2,3], ['a','b'], [4,5])) 
[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), 
 (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5), 
 (3, 'b', 4), (3, 'b', 5)]
>>> list(product([1,2,3]))
[(1,), (2,), (3,)]
>>> list(product([]))
[]
>>> list(product())
[()]
7 là một trình lặp, vì vậy nội dung không được xuất ra bởi
>>> list(product([1,2,3], ['a','b'], [4,5])) 
[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), 
 (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5), 
 (3, 'b', 4), (3, 'b', 5)]
>>> list(product([1,2,3]))
[(1,), (2,), (3,)]
>>> list(product([]))
[]
>>> list(product())
[()]
9.

  • Bạn có thể nhận được sự kết hợp của các phần tử của mỗi danh sách như một tuple với vòng lặp
    import itertools
    import pprint
    
    l1 = ['a', 'b', 'c']
    l2 = ['X', 'Y', 'Z']
    
    p = itertools.product(l1, l2)
    
    print(p)
    # 
    
    print(type(p))
    # 
    
    0. Lưu ý rằng không có gì là đầu ra nếu trình lặp đã đạt đến kết thúc được quay lại trong vòng lặp
    import itertools
    import pprint
    
    l1 = ['a', 'b', 'c']
    l2 = ['X', 'Y', 'Z']
    
    p = itertools.product(l1, l2)
    
    print(p)
    # 
    
    print(type(p))
    # 
    
    0.

for v1, v2 in itertools.product(l1, l2):
    print(v1, v2)
# a X
# a Y
# a Z
# b X
# b Y
# b Z
# c X
# c Y
# c Z

Cũng có thể có được từng yếu tố riêng biệt thay vì một tuple.

for v1 in l1:
    for v2 in l2:
        print(v1, v2)
# a X
# a Y
# a Z
# b X
# b Y
# b Z
# c X
# c Y
# c Z

Giải nén một tuple và danh sách trong Python

Kết quả giống như khi sử dụng các vòng lặp lồng nhau (nhiều vòng).

Cũng có thể chuyển đổi thành một danh sách với các bộ dữ liệu là các yếu tố với

import itertools
import pprint

l1 = ['a', 'b', 'c']
l2 = ['X', 'Y', 'Z']

p = itertools.product(l1, l2)

print(p)
# 

print(type(p))
# 
2.

t = ('one', 'two')
d = {'key1': 'value1', 'key2': 'value2'}
r = range(2)

l_p = list(itertools.product(t, d, r))

pprint.pprint(l_p)
# [('one', 'key1', 0),
#  ('one', 'key1', 1),
#  ('one', 'key2', 0),
#  ('one', 'key2', 1),
#  ('two', 'key1', 0),
#  ('two', 'key1', 1),
#  ('two', 'key2', 0),
#  ('two', 'key2', 1)]

Như bạn có thể thấy từ kết quả ở trên, khi từ điển được lặp lại, các phím được trả về. Nếu bạn cần các giá trị, hãy sử dụng phương thức

import itertools
import pprint

l1 = ['a', 'b', 'c']
l2 = ['X', 'Y', 'Z']

p = itertools.product(l1, l2)

print(p)
# 

print(type(p))
# 
7. Xem bài viết sau đây để biết chi tiết.

  • Lặp lại từ điển (khóa và giá trị) với vòng lặp trong Python

Xem bài viết sau đây để biết thêm thông tin về

import itertools
import pprint

l1 = ['a', 'b', 'c']
l2 = ['X', 'Y', 'Z']

p = itertools.product(l1, l2)

print(p)
# 

print(type(p))
# 
8.

  • Cách sử dụng phạm vi () trong Python

Sử dụng cùng một danh sách (có thể lặp lại) nhiều lần: lặp lại

Bạn có thể chỉ định số lượng lặp lại trong đối số từ khóa

>>> list(product([1,2,3], ['a','b'], [4,5])) 
[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), 
 (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5), 
 (3, 'b', 4), (3, 'b', 5)]
>>> list(product([1,2,3]))
[(1,), (2,), (3,)]
>>> list(product([]))
[]
>>> list(product())
[()]
3. Điều tương tự được sử dụng nhiều lần để tạo ra một sản phẩm Cartesian.

l1 = ['a', 'b']

pprint.pprint(list(itertools.product(l1, repeat=3)))
# [('a', 'a', 'a'),
#  ('a', 'a', 'b'),
#  ('a', 'b', 'a'),
#  ('a', 'b', 'b'),
#  ('b', 'a', 'a'),
#  ('b', 'a', 'b'),
#  ('b', 'b', 'a'),
#  ('b', 'b', 'b')]

Giống như ví dụ sau mà không có

>>> list(product([1,2,3], ['a','b'], [4,5])) 
[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), 
 (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5), 
 (3, 'b', 4), (3, 'b', 5)]
>>> list(product([1,2,3]))
[(1,), (2,), (3,)]
>>> list(product([]))
[]
>>> list(product())
[()]
3.

def product(*args):
    if not args:
        return iter(((),)) # yield tuple()
    return (items + (item,) 
            for items in product(*args[:-1]) for item in args[-1])
0

Nếu nhiều lần lặp được chỉ định:

def product(*args):
    if not args:
        return iter(((),)) # yield tuple()
    return (items + (item,) 
            for items in product(*args[:-1]) for item in args[-1])
1

Giống như ví dụ sau. Lưu ý rằng đó là

for v in p:
    print(v)
# ('a', 'X')
# ('a', 'Y')
# ('a', 'Z')
# ('b', 'X')
# ('b', 'Y')
# ('b', 'Z')
# ('c', 'X')
# ('c', 'Y')
# ('c', 'Z')

for v in p:
    print(v)
1 thay vì
for v in p:
    print(v)
# ('a', 'X')
# ('a', 'Y')
# ('a', 'Z')
# ('b', 'X')
# ('b', 'Y')
# ('b', 'Z')
# ('c', 'X')
# ('c', 'Y')
# ('c', 'Z')

for v in p:
    print(v)
2.

def product(*args):
    if not args:
        return iter(((),)) # yield tuple()
    return (items + (item,) 
            for items in product(*args[:-1]) for item in args[-1])
2

So sánh tốc độ với nhiều vòng (các vòng lồng nhau)

Như đã đề cập ở trên, nhiều vòng lặp (vòng lặp lồng nhau) cho kết quả tương tự như

>>> list(product([1,2,3], ['a','b'], [4,5])) 
[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), 
 (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5), 
 (3, 'b', 4), (3, 'b', 5)]
>>> list(product([1,2,3]))
[(1,), (2,), (3,)]
>>> list(product([]))
[]
>>> list(product())
[()]
1.

def product(*args):
    if not args:
        return iter(((),)) # yield tuple()
    return (items + (item,) 
            for items in product(*args[:-1]) for item in args[-1])
3

Như bạn có thể thấy dưới đây,

>>> list(product([1,2,3], ['a','b'], [4,5])) 
[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), 
 (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5), 
 (3, 'b', 4), (3, 'b', 5)]
>>> list(product([1,2,3]))
[(1,), (2,), (3,)]
>>> list(product([]))
[]
>>> list(product())
[()]
1 thực sự chậm hơn so với các vòng lặp lồng nhau.

Các kết quả có thể khác nhau tùy thuộc vào số lượng các phần tử trong ITEBELD và số lượng vòng lặp, nhưng sau khi hỏi đáp trên Stack Overflow cũng trả lời rằng

>>> list(product([1,2,3], ['a','b'], [4,5])) 
[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), 
 (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5), 
 (3, 'b', 4), (3, 'b', 5)]
>>> list(product([1,2,3]))
[(1,), (2,), (3,)]
>>> list(product([]))
[]
>>> list(product())
[()]
1 chậm hơn.

  • Loops - Python itertools - chậm? - Stack Overflow
  • Python - itertools.praduct Slow so với lồng cho các vòng - Chống chồng

Sau đây là kết quả của việc đo thời gian thực hiện với lệnh ma thuật

for v in p:
    print(v)
# ('a', 'X')
# ('a', 'Y')
# ('a', 'Z')
# ('b', 'X')
# ('b', 'Y')
# ('b', 'Z')
# ('c', 'X')
# ('c', 'Y')
# ('c', 'Z')

for v in p:
    print(v)
6 trong máy tính xách tay Jupyter. Lưu ý rằng nó không thể được đo bằng cách chạy nó dưới dạng mã Python.

  • Đo thời gian thực hiện với thời gian trong Python

Ví dụ về một vòng đôi với 1000 yếu tố:

Kết quả của

>>> list(product([1,2,3], ['a','b'], [4,5])) 
[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), 
 (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5), 
 (3, 'b', 4), (3, 'b', 5)]
>>> list(product([1,2,3]))
[(1,), (2,), (3,)]
>>> list(product([]))
[]
>>> list(product())
[()]
1 nhanh hơn để giải nén.

def product(*args):
    if not args:
        return iter(((),)) # yield tuple()
    return (items + (item,) 
            for items in product(*args[:-1]) for item in args[-1])
4

Các vòng lặp lồng nhau là giống nhau (nhanh hơn một chút) như

>>> list(product([1,2,3], ['a','b'], [4,5])) 
[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), 
 (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5), 
 (3, 'b', 4), (3, 'b', 5)]
>>> list(product([1,2,3]))
[(1,), (2,), (3,)]
>>> list(product([]))
[]
>>> list(product())
[()]
1 khi được giải nén.

def product(*args):
    if not args:
        return iter(((),)) # yield tuple()
    return (items + (item,) 
            for items in product(*args[:-1]) for item in args[-1])
5

Nó nhanh hơn để không giải nén khi sử dụng biểu thức máy phát là phiên bản trình tạo hiểu danh sách, nhưng nó chậm hơn so với

>>> list(product([1,2,3], ['a','b'], [4,5])) 
[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), 
 (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5), 
 (3, 'b', 4), (3, 'b', 5)]
>>> list(product([1,2,3]))
[(1,), (2,), (3,)]
>>> list(product([]))
[]
>>> list(product())
[()]
1 hoặc các vòng lặp lồng nhau.

  • Liệt kê sự hiểu biết trong Python

def product(*args):
    if not args:
        return iter(((),)) # yield tuple()
    return (items + (item,) 
            for items in product(*args[:-1]) for item in args[-1])
6

Ví dụ về việc tính tổng các sản phẩm của mỗi kết hợp. Một lần nữa, việc sử dụng các vòng lồng nhau nhanh hơn

>>> list(product([1,2,3], ['a','b'], [4,5])) 
[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), 
 (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5), 
 (3, 'b', 4), (3, 'b', 5)]
>>> list(product([1,2,3]))
[(1,), (2,), (3,)]
>>> list(product([]))
[]
>>> list(product())
[()]
1.

def product(*args):
    if not args:
        return iter(((),)) # yield tuple()
    return (items + (item,) 
            for items in product(*args[:-1]) for item in args[-1])
7

Trong ví dụ này, việc chuyển biểu thức máy phát sang

for v1, v2 in itertools.product(l1, l2):
    print(v1, v2)
# a X
# a Y
# a Z
# b X
# b Y
# b Z
# c X
# c Y
# c Z
1 nhanh hơn một chút.

def product(*args):
    if not args:
        return iter(((),)) # yield tuple()
    return (items + (item,) 
            for items in product(*args[:-1]) for item in args[-1])
8

Ví dụ về một vòng ba với 100 yếu tố:

Một lần nữa, sử dụng một vòng lặp cho vòng lặp là nhanh nhất.

def product(*args):
    if not args:
        return iter(((),)) # yield tuple()
    return (items + (item,) 
            for items in product(*args[:-1]) for item in args[-1])
9

Như được mô tả ở trên, sự khác biệt giữa một vòng đôi với 1000 phần tử và vòng ba với 100 phần tử chỉ là một vài phần nghìn giây.