【问题标题】:Python - Arranging combinations of list into a list of tuples of various sizesPython - 将列表组合排列成各种大小的元组列表
【发布时间】:2012-10-12 01:19:50
【问题描述】:

我有一个字符串列表:

l = ['a', 'b', 'c']

我想在不同大小的组中创建列表元素的所有可能组合。我希望这是一个元组的列表,但它也可以是列表的列表等。元组的顺序和元组中的元组的顺序无关紧要。元组或元组的元组中都不能重复列表元素。对于上面的列表,我希望是这样的:

[(('a'),('b'),('c')),
 (('a', 'b'), ('c')),
 (('a', 'c'), ('b')),
 (('b', 'c'), ('a')),
 (('a', 'b', 'c'))]

非常感谢任何帮助。

编辑: 我确实要求列表中的每个元组都包含 l 的所有元素。 senderle 和 Antimony,关于遗漏,您都是正确的。

【问题讨论】:

  • 你的意思是a, (b,c,d) 也在那里吗?
  • 这个功能itertools.combinations(iterable, r)可能对你有帮助。
  • 不要(('a', 'b'), ('c', 'd'))(('b', 'c'), ('a', 'd'))(('a', 'c'), ('b', 'd'))也属于输出?
  • @gavinmh 也许更短的示例输入会更清楚。

标签: python list recursion tuples combinations


【解决方案1】:

这是做事的一种方法。不知道有没有更优雅的方法。 itertools 模块具有组合和排列功能,但不幸的是,没有分区功能。

编辑:我的第一个版本不正确,但幸运的是,我已经从我做的一个旧项目中得到了这个。

您还可以通过返回d 而不是d.values() 来获得代表与每个分区关联的边缘位集的唯一整数键。这对于有效地测试一个分区是否是另一个分区的细化很有用。

def connectivityDictSub(num, d, setl, key, i):
    if i >= num:
        assert(key not in d)
        d[key] = setl
    else:
        for ni in range(len(setl)):
            nsetl, nkey = setl[:], key
            for other in nsetl[ni]:
                assert(other != i)
                x,y = sorted((i, other))
                ki = ((2*num-3-x)*x)/2 + y-1
                nkey |= 1<<ki
            nsetl[ni] = nsetl[ni] + [i] #not the same as += since it makes a copy
            connectivityDictSub(num, d, nsetl, nkey, i+1)
        nsetl = setl + [[i]]
        connectivityDictSub(num, d, nsetl, key, i+1)

def connectivityDict(groundSet):
    gset = sorted(set(groundSet))
    d = {}
    connectivityDictSub(len(gset), d, [], 0, 0)
    for setl in d.values():
        setl[:] = [tuple(gset[i] for i in x) for x in setl]
    return map(tuple, d.values())

for x in connectivityDict('ABCD'):
    print x

【讨论】:

  • 应该是for b in xrange(1 &lt;&lt; n):吗?这会产生更多的可能性,而且看起来是正确的。
  • n-1 是故意的。 n 所做的只是在前半段时间生成带有空集的副本。
  • 我认为这有点棘手:我们也需要得到像 (('a', 'd'), ('b'), ('c')) 这样的东西。
  • 不错的收获!我需要稍微调整一下。
  • 我只记得我去年已经这样做了,所以幸运的是我还有代码。
【解决方案2】:

itertools 应该可以完成您想要的大部分工作。

例子:

stuff = [1, 2, 3]
for L in range(0, len(stuff)+1):
  for subset in itertools.combinations(stuff, L):
    print(subset)

这个例子只是为了展示itertools。您必须弄清楚才能获得所需的确切输出。

【讨论】:

  • Itertools 没有任何分区功能,就像提问者想要的那样。
  • 对不起,我应该更清楚地指定列表中的每个顶级元组都应该包含 l 中的所有元素。
  • 不用担心,我知道仅使用 itertools 并不能完成这项工作。只是想指路。 =)
猜你喜欢
  • 1970-01-01
  • 2015-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-10
  • 2013-06-21
  • 1970-01-01
  • 2020-06-14
相关资源
最近更新 更多