Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/grails/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 列表中所有可能的总和,每个列表中只求和一个条目_Python_List_Math - Fatal编程技术网

Python 列表中所有可能的总和,每个列表中只求和一个条目

Python 列表中所有可能的总和,每个列表中只求和一个条目,python,list,math,Python,List,Math,我正在用Python编写一个练习程序,用给定的一组盘子计算我可以放在架子上的所有不同重量 def Weights(t=1,f=1,tn=1,tf=1,thf=1,ff=1,b=45): Max=b+5*t+10*f+20*tn+50*tf+70*thf+90*ff Poss=range(b,Max+1,5) ts=(list((i*5 for i in range(0,t+1)))) fs=(list((i*10 for i in range(0,f+1)))) tns=

我正在用Python编写一个练习程序,用给定的一组盘子计算我可以放在架子上的所有不同重量

def Weights(t=1,f=1,tn=1,tf=1,thf=1,ff=1,b=45):

  Max=b+5*t+10*f+20*tn+50*tf+70*thf+90*ff
  Poss=range(b,Max+1,5)

  ts=(list((i*5 for i in range(0,t+1))))
  fs=(list((i*10 for i in range(0,f+1))))
  tns=(list((i*20 for i in range(0,tn+1))))
  tfs=(list((i*50 for i in range(0,tf+1))))
  thfs=(list((i*70 for i in range(0,thf+1))))
  ffs=(list((i*90 for i in range(0,ff+1))))

Weights()

这给我留下了6张清单。要获得所有的组合,我需要将一个列表的一个元素与另一个列表的一个元素相加。在这一点上,这显然是一个线性代数问题,我只是不知道如何用Python来表达,特别是因为我不想使用插件(无NumPy)

我认为你的方法是错误的,而且你的签名设计也很糟糕:如果你有7种不同的权重呢?我认为输入为元组列表(权重、最大值)更合适。当你开始这样思考时,你就会明白“交叉连接”7个列表也是错误的方法。你想要的是有一个所有简单权重的列表,然后得到所有子集。在Python中有一些很好的power set实现。我特别喜欢这个,因为它不会强制在内存中生成整个电源集,这可能是一个问题:

def功率序列(val):
''为可由整数索引的序列类型生成一个'powerset'。
使用二进制计数枚举成员并返回列表
示例:
>>>powersequence('STR')#字符串
['''S','T','ST','R','SR','TR','STR']
>>>功率序列([0,1,2])#列表
[[], [0], [1], [0, 1], [2], [0, 2], [1, 2], [0, 1, 2]]
>>>幂序列((3,4,5))#元组
[(), (3,), (4,), (3, 4), (5,), (3, 5), (4, 5), (3, 4, 5)]
>>> 
'''
vtype=类型(val);vlen=len(val);vrange=范围(vlen)
返回[reduce(λx,y:x+y,(val[i:i+1]表示变量范围中的i,如果2**i&n),vtype())
对于范围内的n(2**vlen)]
或者,您可以使用实践中更快的方法构建一个(多亏了umutto)

def功率序列(val):
s=列表(iterable)
返回链。从_iterable(范围(len(s)+1)内r的组合(s,r))
因此,算法是:

  • 建立所有简单权重的单一列表(将您的
    ts
    fs
    ,…)
  • 使用
    powersequence
    生成功率集
  • 对每个子集中的所有项目求和
  • 推送结果以设置为筛选唯一性
  • def所有权重(ws):
    simpleWeights=[0]#只添加一次0
    对于ws中的(w,c):
    SimpleLights=SimpleLights+[w]*c
    allWeights=(powersequence中子集的总和(子集)(simpleWeights))
    返回集(所有权重)#过滤器唯一性
    all=所有权重([(1,1)、(5,1)、(10,1)、(20,1)、(50,1)、(70,1)、(90,1)])
    对于所有的w:
    打印(w)
    
    请注意,唯一性条件强制将整个集合具体化到内存中,所以这可能是此代码可以解决的问题大小的限制因素

    更新

    事实上,jez是对的:按硬币生成列表的速度将明显快于迭代连接列表的
    powersequence

    def所有权重(ws):
    simpleWeights=[]
    对于ws中的(w,c):
    append(列表((i*w表示范围(0,c+1)中的i)))
    allWeights=(itertools.product(*simpleWeights)中子集的总和(子集))#注意simpleWeights前面的“*”!
    返回集(所有权重)#过滤器唯一性
    
    我认为你的方法是错误的,而且你的签名是糟糕的设计:如果你有7种不同的重量呢?我认为输入为元组列表(权重、最大值)更合适。当你开始这样思考时,你就会明白“交叉连接”7个列表也是错误的方法。你想要的是有一个所有简单权重的列表,然后得到所有子集。在Python中有一些很好的power set实现。我特别喜欢这个,因为它不会强制在内存中生成整个电源集,这可能是一个问题:

    def功率序列(val):
    ''为可由整数索引的序列类型生成一个'powerset'。
    使用二进制计数枚举成员并返回列表
    示例:
    >>>powersequence('STR')#字符串
    ['''S','T','ST','R','SR','TR','STR']
    >>>功率序列([0,1,2])#列表
    [[], [0], [1], [0, 1], [2], [0, 2], [1, 2], [0, 1, 2]]
    >>>幂序列((3,4,5))#元组
    [(), (3,), (4,), (3, 4), (5,), (3, 5), (4, 5), (3, 4, 5)]
    >>> 
    '''
    vtype=类型(val);vlen=len(val);vrange=范围(vlen)
    返回[reduce(λx,y:x+y,(val[i:i+1]表示变量范围中的i,如果2**i&n),vtype())
    对于范围内的n(2**vlen)]
    
    或者,您可以使用实践中更快的方法构建一个(多亏了umutto)

    def功率序列(val):
    s=列表(iterable)
    返回链。从_iterable(范围(len(s)+1)内r的组合(s,r))
    
    因此,算法是:

  • 建立所有简单权重的单一列表(将您的
    ts
    fs
    ,…)
  • 使用
    powersequence
    生成功率集
  • 对每个子集中的所有项目求和
  • 推送结果以设置为筛选唯一性
  • def所有权重(ws):
    simpleWeights=[0]#只添加一次0
    对于ws中的(w,c):
    SimpleLights=SimpleLights+[w]*c
    allWeights=(powersequence中子集的总和(子集)(simpleWeights))
    返回集(所有权重)#过滤器唯一性
    all=所有权重([(1,1)、(5,1)、(10,1)、(20,1)、(50,1)、(70,1)、(90,1)])
    对于所有的w:
    打印(w)
    
    请注意,唯一性条件强制将整个集合具体化到内存中,所以这可能是此代码可以解决的问题大小的限制因素

    更新

    事实上,jez是对的:按硬币生成列表的速度将明显快于迭代连接列表的
    powersequence

    def所有权重
    
    import itertools
    
    b = [45]  # I assume this represents the "bar" and that it's not optional
    ts = [0, 5, 10, 15]
    fs = [0, 10]
    
    combos = itertools.product(b, ts, fs)
    for combo in combos: print(list(combo))
    
    [45, 0, 0]
    [45, 0, 10]
    [45, 5, 0]
    [45, 5, 10]
    [45, 10, 0]
    [45, 10, 10]
    [45, 15, 0]
    [45, 15, 10]
    
    totals = [sum(combo) for combo in itertools.product(b, ts, fs)]
    
    import itertools
    
    def PossibleWeights(*weights):
        return list(itertools.product(*[[weightset] if isinstance(weightset, (int, float)) else [sum(weightset[:i]) for i in range(len(weightset)+1)] for weightset in weights]))
    
    d = {}
    for combo in PossibleWeights( 45, [10]*2, [5]*3 ):
        d[sum(combo)] = combo
    
    for total, combo in sorted(d.items()):
        print('sum(%r) = %r' % (combo, total))
    
    sum((45, 0, 0)) = 45
    sum((45, 0, 5)) = 50
    sum((45, 10, 0)) = 55
    sum((45, 10, 5)) = 60
    sum((45, 20, 0)) = 65
    sum((45, 20, 5)) = 70
    sum((45, 20, 10)) = 75
    sum((45, 20, 15)) = 80