python 2.5.2中的排列

时间:2010-04-22 10:16:22

标签: python list permutation

我有一个输入数字列表,例如

671.00   
1,636.00
436.00
9,224.00

我希望生成所有可能的总和,并为其输入ID,例如:

671.00 + 1,636.00 = 2,307.00
671.00 + 436.00 = 1,107.00
671.00 + 9,224.00 = 9,224.00
671.00 + 1,636.00 + 436.00 = 2,743.00
...

我想用Python做 我目前的限制是: a)我现在正在学习python(这是想法的一部分) b)我将不得不使用Python 2.5.2(没有intertools)

我想我找到了一段可能有用的代码:

def all_perms(str):
    if len(str) <=1:
        yield str
    else:
        for perm in all_perms(str[1:]):
            for i in range(len(perm)+1):
                #nb str[0:1] works in both string and list contexts
                yield perm[:i] + str[0:1] + perm[i:]

(来自these guys

但我不确定如何在我的建议中使用它。 有人可以提供一些提示和帮助代码吗?

欢呼声,

F。

3 个答案:

答案 0 :(得分:3)

排列是关于采取有序的一组事物并移动这些东西(即改变顺序)。您的问题是关于列表中组合的事情。

现在,枚举组合的一种简单方法是将列表中的条目映射到数字中的位。例如,假设如果设置了位#0(即1),则数字lst[0]参与组合,如果设置了位#1,则lst[1]参与组合等。方式,范围0 <= n < 2**(len(lst))中的数字标识lst成员的所有可能组合,包括空成员(n = 0)和整个lstn = 2**(len(lst)) - 1)。< / p>

您只需要2项或更多项的组合,即只需要在其二进制表示中至少有两个非零位的组合ID。以下是如何识别这些:

def HasAtLeastTwoBitsSet(x) :
    return (x & (x-1)) != 0

# Testing:
>>> [x for x in range(33) if HasAtLeastTwoBitsSet(x)]
[3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]

下一步是提取由组合ID标识的列表成员的组合。由于列表推导的强大功能,这很容易:

def GetSublistByCombination(lst, combination_id) :
    res = [x for (i,x) in enumerate(lst) if combination_id & (1 << i)]
    return res

# Testing:
>>> GetSublistByCombination([0,1,2,3], 1)
[0]
>>> GetSublistByCombination([0,1,2,3], 3)
[0, 1]
>>> GetSublistByCombination([0,1,2,3], 12)
[2, 3]
>>> GetSublistByCombination([0,1,2,3], 15)
[0, 1, 2, 3]

现在让我们创建一个生成所有总和的生成器及其字符串表示:

def IterAllSums(lst) :
    combinations = [i for i in range(1 << len(lst)) if HasAtLeastTwoBitsSet(i)]
    for comb in combinations :
        sublist = GetSublistByCombination(lst, comb)
        sum_str = '+'.join(map(str, sublist))
        sum_val = sum(sublist)
        yield (sum_str, sum_val)

最后,让我们使用它:

>>> for sum_str, sum_val in IterAllSums([1,2,3,4]) : print sum_str, sum_val

1+2 3
1+3 4
2+3 5
1+2+3 6
1+4 5
2+4 6
1+2+4 7
3+4 7
1+3+4 8
2+3+4 9
1+2+3+4 10

答案 1 :(得分:0)

下面的代码生成给定列表的所有“子集”(空集除外),即返回列表列表。

def all_sums(l): #assumes that l is non-empty
    if len(l)==1:
        return ([[l[0]]])
    if len(l)==0:
        return []
    result = []
    for i in range(0,len(l)):
        result.append([l[i]])
        for p in all_sums(l[i+1:]):
            result.append([l[i]]+p)
    return result

现在你也可以为输出写一个简短的函数doit

def doit(l):
    mylist = all_sums(l)
    print mylist
    for i in mylist:
        print str(i) + " = " + str(sum(i))

doit([1,2,3,4])

答案 2 :(得分:0)

使用itertools(Python&gt; = 2.6)将是:

from itertools import *
a=[1,2,3,4]
sumVal=[tuple(imap(sum,combinations(a,i))) for i in range(2,len(a)+1)]