Python 返回某个数的和数的函数。py
我需要编写一个函数,返回通过添加列表中的数字来达到某个数字的方法数。例如:Python 返回某个数的和数的函数。py,python,Python,我需要编写一个函数,返回通过添加列表中的数字来达到某个数字的方法数。例如: print(p([3,5,8,9,11,12,20], 20)) should return:5 我写的代码是: def pow(lis): power = [[]] for lst in lis: for po in power: power = power + [list(po)+[lst]] return power def p(lst, n):
print(p([3,5,8,9,11,12,20], 20))
should return:5
我写的代码是:
def pow(lis):
power = [[]]
for lst in lis:
for po in power:
power = power + [list(po)+[lst]]
return power
def p(lst, n):
counter1 = 0
counter2 = 0
power_list = pow(lst)
print(power_list)
for p in power_list:
for j in p:
counter1 += j
if counter1 == n:
counter2 += 1
counter1 == 0
else:
counter1 == 0
return counter2
pow()
是一个返回列表的所有子集的函数,p
应返回达到数字n的方法数。我一直得到零输出,我不明白为什么。我很想听听你对此的意见。
提前感谢。一个带有一个计数器的一次性解决方案,可以最大限度地减少添加
def one_pass_sum(L,target):
sums = [0]
cnt = 0
for x in L:
for y in sums[:]:
z = x+y
if z <= target :
sums.append(z)
if z == target : cnt += 1
return cnt
但顺序很重要:z
必须被视为此处的后代,以获得良好的计数(多亏了pm2ring)
对于大型列表,这可能非常快(n*target
additions)
例如:
>>> enhanced_sum_with_lists(range(1,100),2500)
875274644371694133420180815
是在61毫秒内获得的。用第一种方法计算它需要宇宙的年龄 一种带有一个计数器的一次性解决方案,可最大限度地减少添加量
def one_pass_sum(L,target):
sums = [0]
cnt = 0
for x in L:
for y in sums[:]:
z = x+y
if z <= target :
sums.append(z)
if z == target : cnt += 1
return cnt
但顺序很重要:z
必须被视为此处的后代,以获得良好的计数(多亏了pm2ring)
对于大型列表,这可能非常快(n*target
additions)
例如:
>>> enhanced_sum_with_lists(range(1,100),2500)
875274644371694133420180815
是在61毫秒内获得的。用第一种方法计算它需要宇宙的年龄 代码中有两个输入错误:
counter1==0
是一个布尔值,它不会重置任何内容
此版本应适用于:
def p(lst, n):
counter2 = 0
power_list = pow(lst)
for p in power_list:
counter1 = 0 #reset the counter for every new subset
for j in p:
counter1 += j
if counter1 == n:
counter2 += 1
return counter2
代码中有两个输入错误:
counter1==0
是一个布尔值,它不会重置任何内容
此版本应适用于:
def p(lst, n):
counter2 = 0
power_list = pow(lst)
for p in power_list:
counter1 = 0 #reset the counter for every new subset
for j in p:
counter1 += j
if counter1 == n:
counter2 += 1
return counter2
正如tobias_k和Faibbus提到的,您有两处输入错误:
counter1==0
,而不是counter1=0
。counter1==0
生成一个布尔对象True
或False
,但由于没有指定该表达式的结果,因此结果会被丢弃。它不会引发语法错误,因为未赋值的表达式是合法的Python
正如约翰·科尔曼(John Coleman)和B.M.提到的那样,创建完整的功率集,然后测试每个子集以确定其总和是否正确,这是不高效的。如果输入序列很小,这种方法是可以的,但是对于中等大小的序列来说,速度非常慢,如果您实际上创建了一个包含子集的列表,而不是使用生成器并在生成子集时测试子集,那么很快就会耗尽RAM
B.M.的第一个解决方案非常有效,因为它不会产生大于目标和的子集。(我不确定B.m.对基于dict的解决方案做了什么…)
但我们可以通过对总和列表进行排序来增强这种方法。这样,一旦我们检测到一个过高的总和,我们就可以打破内部的for
循环。诚然,我们需要在外部for
循环的每次迭代中对sums
列表进行排序,但幸运的是Python的TimSort非常有效,并且经过优化,可以处理包含已排序子序列的列表的排序,因此它非常适合此应用程序
def subset_sums(seq, goal):
sums = [0]
for x in seq:
subgoal = goal - x
temp = []
for y in sums:
if y > subgoal:
break
temp.append(y + x)
sums.extend(temp)
sums.sort()
return sum(1 for y in sums if y == goal)
# test
lst = [3, 5, 8, 9, 11, 12, 20]
total = 20
print(subset_sums(lst, total))
lst = range(1, 41)
total = 70
print(subset_sums(lst, total))
输出
5
28188
使用
lst=range(1,41)
和total=70
,此代码比B.M.列表版本快约3倍。正如tobias_k和Faibbus提到的,您有两处输入错误:counter1==0
而不是counter1=0
。counter1==0
生成一个布尔对象True
或False
,但由于没有指定该表达式的结果,因此结果会被丢弃。它不会引发语法错误,因为未赋值的表达式是合法的Python
正如约翰·科尔曼(John Coleman)和B.M.提到的那样,创建完整的功率集,然后测试每个子集以确定其总和是否正确,这是不高效的。如果输入序列很小,这种方法是可以的,但是对于中等大小的序列来说,速度非常慢,如果您实际上创建了一个包含子集的列表,而不是使用生成器并在生成子集时测试子集,那么很快就会耗尽RAM
B.M.的第一个解决方案非常有效,因为它不会产生大于目标和的子集。(我不确定B.m.对基于dict的解决方案做了什么…)
但我们可以通过对总和列表进行排序来增强这种方法。这样,一旦我们检测到一个过高的总和,我们就可以打破内部的for
循环。诚然,我们需要在外部for
循环的每次迭代中对sums
列表进行排序,但幸运的是Python的TimSort非常有效,并且经过优化,可以处理包含已排序子序列的列表的排序,因此它非常适合此应用程序
def subset_sums(seq, goal):
sums = [0]
for x in seq:
subgoal = goal - x
temp = []
for y in sums:
if y > subgoal:
break
temp.append(y + x)
sums.extend(temp)
sums.sort()
return sum(1 for y in sums if y == goal)
# test
lst = [3, 5, 8, 9, 11, 12, 20]
total = 20
print(subset_sums(lst, total))
lst = range(1, 41)
total = 70
print(subset_sums(lst, total))
输出
5
28188
使用
lst=range(1,41)
和total=70
,此代码的速度大约是B.M.列表版本的3倍。由于pow
是一个内置函数,您可能需要选择不同的名称。在任何情况下,如果已知所有的数字都是正数,那么检查所有的子集都是多余的。此外——除非这是家庭作业,并且要求您从头开始做所有事情,否则使用itertools
模块是枚举子集的最简单方法。counter1==0
应该是counter1=0
(两次)。因打字错误而关闭。此外,可以简化为counter2=sum(电源列表中p的sum(p)==n)
如果下面的一个答案解决了您的问题,您应该接受它(单击相应答案旁边的复选标记)。这有两件事。它让每个人都知道你的问题已经解决到令你满意的程度,并让帮助你的人相信你的帮助。有关详细说明,请参阅。由于pow
是一个内置函数,因此您可能需要选择其他名称。在任何情况下,如果所有的数字都是正数,那么检查所有的子集都是多余的。另外——除非这是家庭作业,并且你需要使用