简体   繁体   English

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

[英]getting every possible combination in a list

suppose I had something like this: 假设我有这样的事情:

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)

and I wanted to get every combination of files without repeating combinations that have already been done (once cat_dog is done do not do dog_cat again). 而且我想获取文件的每个组合,而不必重复已经完成的组合(一旦完成cat_dog,就不要再执行dog_cat了)。 Is there a way I could do this? 有办法吗? My real list is in alphabetical order, if that makes any difference. 我的实际列表按字母顺序排列(如果有任何区别)。

In reality what you're asking how to do is produce all combinations of two items taken in the list of names (as opposed to all the possible combination of them). 实际上,您要问的是如何生成名称列表中两个项目的所有组合(而不是它们的所有可能组合)。

That means you can use the built-in itertools.combinations() generator function to easily (and efficiently) generate pairs of the names you want with no repeats: 这意味着您可以使用内置的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')

Pairs processed: 对已处理:

('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')

How about itertools.combinations ? 怎么样itertools.combinations

Usage example: 用法示例:

>>> 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)]

First argument is an iterable, second is r , length of subsequences returned. 第一个参数是可迭代的,第二个参数是r ,返回的子序列的长度。

You can then concatenate the results with ease using map or a comprehension: 然后,您可以使用map或comprehension轻松连接结果:

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

x in the lambda is a r -sized tuple. λ中的x是一个r大小的元组。

Result of the above would be: 以上结果将是:

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

you can also do it as a generator: 您也可以将其用作生成器:

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)

After the first loop, the contents of tuples is: 在第一个循环之后, 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')
import itertools
import cPickle

def unique_pairs(lst):
    return itertools.combinations(lst, 2)

FNAME = "file_{0}".format
def load_pickle(fname):
    with open(fname) as inf:
        return cPickle.load(inf)

def naive_method(lst):
    # load each file every time it is requested
    for x,y in unique_pairs(lst):
        input1 = load_pickle(FNAME(x))
        input2 = load_pickle(FNAME(y))
        # do something with input1 and input2

def better_method(lst):
    # if you have enough memory for it!
    dat = [load_pickle(FNAME(i)) for i in lst]
    for x,y in unique_pairs(range(len(lst))):
        input1 = dat[x]
        input2 = dat[y]
        # do something with input1 and input2

There's itertools that can perform combinations and permutations (you'd want the former). itertools可以执行组合和排列(您希望使用前者)。 As far as I can tell, you can't really specify the output format, so you'd get "catdog" as output, but the doc page gives you an idea of how the combinations function works, so you can adapt it to build what you need. 据我所知,您不能真正指定输出格式,因此将获得“ catdog”作为输出,但是doc页面使您了解了组合功能的工作原理,因此可以对其进行调整以进行构建您需要什么。

An alternative for combination creation, with no module import. 无需模块导入即可创建组合的替代方法。 Similar to @Nate's answer, but marginally less complex, creating a copy with single items and reducing on the fly (rather than generating a list of pairs and reducing by list search): 与@Nate的答案类似,但稍微复杂一些,创建一个包含单个项目的副本并快速减少(而不是生成成对列表并通过列表搜索来减少):

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

pairs = []
for a in L1:
    Laux.remove(a)
    for b in Laux:
        pairs += [(a,b)]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM