【问题标题】:getting every possible combination in a list在列表中获取所有可能的组合
【发布时间】:2011-02-24 14:51:19
【问题描述】:

假设我有这样的事情:

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 了)。有没有办法我可以做到这一点?我的真实列表是按字母顺序排列的,如果这有什么不同的话。

【问题讨论】:

标签: python list combinations


【解决方案1】:

实际上,您要问的是如何生成名称列表中 两个 项的所有组合(而不是 all 它们的可能组合)。

这意味着您可以使用内置的 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')

【讨论】:

    【解决方案2】:

    你也可以作为生成器来做:

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

    【讨论】:

    • 这不是一个好方法。看看 itertools 解决方案! Itertools 避免了必须预先生成完整列表 - 在此实现中,元组列表的长度为 n^2 项。 itertools 解决方案不需要存储列表。
    【解决方案3】:

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

    lambda 中的x 是一个r 大小的元组。

    上面的结果是:

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

    【讨论】:

      【解决方案4】:
      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
      

      【讨论】:

        【解决方案5】:

        itertools 可以执行组合和排列(您需要前者)。据我所知,你不能真正指定输出格式,所以你会得到“catdog”作为输出,但是文档页面让你了解组合函数是如何工作的,所以你可以调整它来构建你需要什么。

        【讨论】:

          【解决方案6】:

          组合创建的替代方法,没有模块导入。类似于@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)]
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-05-09
            • 2013-10-06
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多