获取列表中的所有可能组合

7 投票
6 回答
7771 浏览
提问于 2025-04-16 12:28

假设我有这样的东西:

L1=['cat', 'dog', 'fish', 'rabbit', 'horse', 'bird', 'frog', 'mouse'...]

for x in L1:
    input1= open('file_%s'%(x), 'r')
    file1= pickle.load(input1)
    for x in L1:
        input2= open('file_%s'%(x), 'r')
        file2= pickle.load(input2)

我想要得到所有文件的组合,但不想重复已经做过的组合(比如说,做完 cat_dog 之后就不再做 dog_cat)。有没有办法做到这一点?我的真实列表是按字母顺序排列的,这样会有影响吗?

6 个回答

5

那你觉得 itertools.combinations 怎么样呢?

使用示例:

>>> list(itertools.combinations([1, 2, 3, 4, 5, 6], 2))
[(1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 3), (2, 4), (2, 5), (2, 6), (3, 4),
(3, 5), (3, 6), (4, 5), (4, 6), (5, 6)]

第一个参数是一个可迭代的对象,第二个参数是 r,表示返回的子序列的长度。

然后你可以很方便地使用 map 或者列表推导式来连接结果:

map(lambda x: x[0] + "_" + x[1], itertools.combinations(["cat", "dog", "fish"], 2)))

x 在这个 lambda 表达式里是一个大小为 r 的元组。

上面的结果会是:

['cat_dog', 'cat_fish', 'dog_fish']
22

实际上,你想要做的就是从名字列表中生成两个项目的所有组合,而不是所有可能的组合。

这意味着你可以使用内置的 itertools.combinations() 函数,这样可以轻松(而且高效)地生成你想要的名字对,而且不会有重复:

L1 = ['cat', 'dog', 'fish', 'rabbit', 'horse', 'bird', 'frog', 'mouse']

for pair in combinations(L1, 2):
    print(pair)
    input1 = open('file_%s' % pair[0], 'r')
    input2 = open('file_%s' % pair[1], 'r')

处理过的对:

('cat', 'dog')
('cat', 'fish')
('cat', 'rabbit')
('cat', 'horse')
('cat', 'bird')
('cat', 'frog')
('cat', 'mouse')
('dog', 'fish')
('dog', 'rabbit')
('dog', 'horse')
('dog', 'bird')
('dog', 'frog')
('dog', 'mouse')
('fish', 'rabbit')
('fish', 'horse')
('fish', 'bird')
('fish', 'frog')
('fish', 'mouse')
('rabbit', 'horse')
('rabbit', 'bird')
('rabbit', 'frog')
('rabbit', 'mouse')
('horse', 'bird')
('horse', 'frog')
('horse', 'mouse')
('bird', 'frog')
('bird', 'mouse')
('frog', 'mouse')
5

你也可以把它做成一个生成器:

L1=['cat', 'dog', 'fish', 'rabbit', 'horse', 'bird', 'frog', 'mouse']
tuples = [(x,y) for x in L1 for y in L1 if x != y]
for entry in tuples:
    if (entry[1], entry[0]) in tuples:
        tuples.remove((entry[1],entry[0]))
for pair in tuples:
    input1= open('file_%s'%(pair[0]), 'r')
    file1= pickle.load(input1)
    input2= open('file_%s'%(pair[1]), 'r')
    file2= pickle.load(input2)

在第一次循环之后,tuples 的内容是:

('cat', 'dog')
('cat', 'fish')
('cat', 'rabbit')
('cat', 'horse')
('cat', 'bird')
('cat', 'frog')
('cat', 'mouse')
('dog', 'fish')
('dog', 'rabbit')
('dog', 'horse')
('dog', 'bird')
('dog', 'frog')
('dog', 'mouse')
('fish', 'rabbit')
('fish', 'horse')
('fish', 'bird')
('fish', 'frog')
('fish', 'mouse')
('rabbit', 'horse')
('rabbit', 'bird')
('rabbit', 'frog')
('rabbit', 'mouse')
('horse', 'bird')
('horse', 'frog')
('horse', 'mouse')
('bird', 'frog')
('bird', 'mouse')
('frog', 'mouse')

撰写回答