如何获得一系列列表的笛卡尔积?

在本教程中,我将演示可用于获取一系列列表的笛卡尔积的不同方法。您将学习 3 种查找一系列列表的笛卡尔积的方法。
让我们首先回顾一下 Python 列表。


什么是 Python 列表?

Python 中的列表一种按有序序列存储数据元素的数据结构。它与其他编程语言(如 C++、Java 等)中的数组非常相似。列表中存储的数据项可以是不同的类型(例如整数、字符串等)。
列表中的元素可以使用它们的索引直接访问。Python 列表是可变的,这意味着您可以在创建列表后添加、删除和修改元素。

在 Python 中可以使用方括号创建列表[]这里有些例子:

colours =  ['red', 'green', 'blue', 'pink']
 
my_list = [4, 'flower', 87, 25.36]

现在您已经记住了什么是列表,让我向您解释一下笛卡尔积。

什么是笛卡尔积?

在数学和计算机科学中,两个集合 A 和 B 的笛卡尔积是所有可能的有序对 (a, b) 的集合,其中 a 是 A 的元素,b 是 B 的元素。笛卡尔积表示为A×B。

例如,如果 A = {1, 2} 且 B = {3, 4},则它们的笛卡尔积 A × B 为:

A × B = { (1, 3), (1, 4), (2, 3), (2, 4) }

请注意,由于笛卡尔积是有序的,因此A x B 与 B x A 不同。

笛卡尔积 B x A 为:

B × A = { (3, 1), (3, 2), (4, 1), (4, 2) }

笛卡尔积还可以扩展到两个以上的集合。例如,如果 A = {1, 2},B = {3, 4},C = {5, 6},则它们的笛卡尔积 A × B × C 为:

A × B × C = { (1, 3, 5), (1, 3, 6), (1, 4, 5), (1, 4, 6), (2, 3, 5), (2, 3, 6), (2, 4, 5), (2, 4, 6) }

两个集合 A 和 B 的笛卡尔积的基数是 A x B 中有序对的总数。

另请阅读:如何在 Python 中划分列表中的每个元素?


查找一系列列表的笛卡尔积的方法

在 Python 中,可以使用 3 种方法来查找一系列列表的笛卡尔积。让我们一一看看它们。

方法 1:使用列表推导式

列表理解 是一种编写更短或简洁的语法的方法,用于根据现有列表创建新列表。您可以使用列表理解来查找列表的笛卡尔积。

下面是使用列表理解查找两个列表的笛卡尔积的示例。

list1 = [2, 5]
list2 = ['car', 'cycle']
 
# list1 x list2
cartesian_product = [(a, b) for a in list1 for b in list2]
 
print(cartesian_product)

输出:

[(2, 'car'), (2, 'cycle'), (5, 'car'), (5, 'cycle')]

上面的示例由两个独立的列表组成,但您也可以传递任何可迭代集合或可迭代的组合。同样,您可以找到一系列列表的笛卡尔积,如下所示:

lists = [
    [10, 30],
    ['rose', 'tulip'],
    [1.5, 3.6]
]
 
# lists[0] x lists[1] x lists[2]
cartesian_product = [(a, b, c) for a in lists[0] for b in lists[1] for c in lists[2]]
 
print(cartesian_product)

这与编写 3 个嵌套的 for 循环相同:

cartesian_product = []
 
# lists[0] x lists[1] x lists[2]
for a in lists[0]:
    for b in lists[1]:
        for c in lists[2]:
            cartesian_product.append((a, b, c))
             
print(cartesian_product)

上面的代码将输出相同的内容:

[(10, 'rose', 1.5), (10, 'rose', 3.6), (10, 'tulip', 1.5), (10, 'tulip', 3.6), (30, 'rose', 1.5), (30, 'rose', 3.6), (30, 'tulip', 1.5), (30, 'tulip', 3.6)]

方法2:使用递归

您还可以使用递归查找一系列列表的笛卡尔积

def cartesian_product(lists):
    if not lists:
        yield ()
    else:
        for a in lists[0]:
            for num in cartesian_product(lists[1:]):
                yield (a,) + num
                 
                 
list1 = [3, 67]
list2 = [10, 4]
ans = list(cartesian_product([list1, list2]))
print(ans)

输出:

[(3, 10), (3, 4), (67, 10), (67, 4)]

推荐阅读:Python 产量


方法 3:使用 itertools.product()

itertools模块是 Python 中的标准库模块,提供了用于处理迭代器和可迭代对象的函数集合。itertools模块中的函数可用于生成常见任务的迭代器,例如迭代一组项目的所有可能组合和排列、重复项目和对项目进行分组。

该模块中的功能之一是product().

product(*iterables, repeat=1)– 此函数生成输入迭代的笛卡尔积,可选repeat参数指定每个输入迭代应重复的次数。

以下是如何使用该itertools.product()函数查找一系列列表的笛卡尔积。

from itertools import product
 
list1 = [2, 'car']
list2 = [10, 4]
 
ans = list(product(list1, list2))
 
print(ans)

输出:

[(2, 10), (2, 4), ('car', 10), ('car', 4)]

您还可以直接将一系列列表传递给函数,如下所示:

from itertools import product
 
lists = [[3, 12], ['hello', 'world'], [4.2, 8.4]]
 
for i in product([3, 12], ['hello', 'world'], [4.2, 8.4]):
    print(i)

输出:

(3, 'hello', 4.2)
(3, 'hello', 8.4)
(3, 'world', 4.2)
(3, 'world', 8.4)
(12, 'hello', 4.2)
(12, 'hello', 8.4)
(12, 'world', 4.2)
(12, 'world', 8.4)

结论

在本教程中,您学习了如何使用 Python 查找一系列列表的笛卡尔积。您看到了 3 种不同的方法来实现结果。方法如下:

使用以下 3 种方法获取一系列列表的笛卡尔积。

  • 使用列表理解
  • 使用递归
  • 使用 itertools.product() 函数

参考