高效及;在给定范围内找到列表中所有可能的子列表的python方法,以及将其中的所有元素相乘后的最小乘积?
我已经完成了这两件事。高效及;在给定范围内找到列表中所有可能的子列表的python方法,以及将其中的所有元素相乘后的最小乘积?,python,list,python-2.7,python-3.x,reduce,Python,List,Python 2.7,Python 3.x,Reduce,我已经完成了这两件事。 查找给定范围内列表的所有可能子列表(i,j) A = [ 44, 55, 66, 77, 88, 99, 11, 22, 33 ] Let, i = 2 and j = 4 然后,给定范围(2,4)中列表“A”的可能子列表为: [66], [66,77], [66,77,88], [77], [77,88], [88] 并且,将子列表的所有元素叠加后的结果乘积的最小值: 因此,将上述子列表中的所有元素相乘后的结果列表将变为 X = [66, 5082, 44721
(i,j)
A = [ 44, 55, 66, 77, 88, 99, 11, 22, 33 ]
Let, i = 2 and j = 4
然后,给定范围(2,4)
中列表“A”
的可能子列表为:[66], [66,77], [66,77,88], [77], [77,88], [88]
因此,将上述子列表中的所有元素相乘后的结果列表将变为
X = [66, 5082, 447216, 77, 6776, 88]`
现在,上面列表中的最小值是min(X)
即66
i, j = 2, 4
A = [ 44, 55, 66, 77, 88, 99, 11, 22, 33 ]
O, P = i, i
mini = A[O]
while O <= j and P <= j:
if O == P:
mini = min(mini, reduce(lambda x, y: x * y, [A[O]]))
else:
mini = min(mini, reduce(lambda x, y: x * y, A[O:P + 1]))
P += 1
if P > j:
O += 1
P = O
print(mini)
i,j=2,4
A=[44,55,66,77,88,99,11,22,33]
O、 P=i,i
mini=A[O]
而O看一看aitertools.compositions()
在循环中通过子列表调用它,其他参数从1到子列表的长度不等
这肯定需要“更多的时间来执行更大的列表和范围”,我认为这是不可避免的。但可能比你的方法快得多。测量并查看。首先,给定列表和索引范围,我们可以得到子列表A[i:j+1]
[66, 77, 88]
对于正整数a
和b
,a*b
不小于a
或b
。所以你不需要做乘法,两个或更多元素的乘法不可能得到更小的结果。此列表的最小值是所有乘法结果的最小值
因此,结果是:
min(A[i : j + 1])
要生成子列表,只需在列表中为
循环生成两个嵌套的:
def sublists(l,i,j):
return [l[m:n+1] for m in range(i,j+1) for n in range(m,j+1)]
例如:
>>> sublists(A,2,4)
[[66], [66, 77], [66, 77, 88], [77], [77, 88], [88]]
要查找最小产品,请执行以下操作:
>>> min(map(prod, sublists(A,2,4)))
66
(您从numpy
导入prod
,或将其定义为def prod(x):return reduce(lambda i,j:i*j,x)
)编辑:快速解决方案:
min(A[i:j+1])
因为所有的数字都是正整数,您需要找到A[i:j+1]
list
切片,它还将包含长度为1的子列表所有此类子列表的最小乘积将是A[i:j+1]
切片中的最小数。
另一种解决方案:
min(A[i:j+1])
当您需要查找子列表的最大乘积或需要A[i:j+1]
列表切片的所有可能组合时,以下方法将非常有用。
我们将用它来解决这个问题。我们可以分三步来完成
步骤1:获取列表的切片
my_list = A[i:j+1]
import itertools
my_combinations = []
for x in range(1, len(my_list)+1):
my_combinations.extend(list(itertools.combinations(my_list,x)))
my_combinations
[(66,), (77,), (88,), (66, 77), (66, 88), (77, 88), (66, 77, 88)]
这将为我们提供工作的机会
my_list = A[2:5]
my_list
[66, 77, 88]
步骤2生成所有可能的组合:
my_list = A[i:j+1]
import itertools
my_combinations = []
for x in range(1, len(my_list)+1):
my_combinations.extend(list(itertools.combinations(my_list,x)))
my_combinations
[(66,), (77,), (88,), (66, 77), (66, 88), (77, 88), (66, 77, 88)]
iterools.combines从返回元素的r长度子序列
输入不可编辑
因此,我们将使用它生成长度为1到等于my_list
长度的子序列。我们将得到一个元组列表,每个元素都是一个子序列
步骤3:找到所有可能组合的最小乘积
products_list = [reduce(lambda i,j:i*j, x) for x in my_combinations]
[66, 77, 88, 5082, 5808, 6776, 447216]
min(products_list)
66
获取子序列后,我们应用列表理解和reduce()
来获取my\u组合中所有子序列的产品列表。然后我们应用min()
函数从products\u列表
中得到最小乘积,这将给出我们的答案。接受的答案对于所有正整数都是正确的,因为您无法将最小元素乘以任何数字,从而得到较小的结果。如果得到的所有切片都大于长度1,则可能更有意义
如果要计算它,则可以使用itertools.islice
获取每个切片,并使用生成器表达式获取最小值:
from itertools import islice
from operator import mul
print(min(reduce(mul, islice(A, n, k + 1), 1)
for n in range(i, j + 1) for k in range(n, j + 1)))
66
如果对于i=0和j=4,您认为(44、55、66、88)
是一个合法的切片,那么您需要使用itertools.compositions
def solution(a_list):
sub = [[]]
for i in range(len(a_list)):
for j in range(len(a_list)):
if(i == j):
sub.append([a_list[i]])
elif(i > j):
sub.append([a_list[j],a_list[i]])
sub.append(a_list)
return sub
solution([10, 20, 30])
列表中元素的可能范围是多少?比如他们是积极的吗?它们是整数吗?@YuHao,是的。。正整数!谢谢,先生,如果有多个这样的可能的子列表具有相同的最小乘积,如何获得最长的子列表(长子范围)?@Srikanth假设a
和b
为正整数,a*b
仅当b
为1
时才等于a
。因此,要获得最长的子列表,请查找1
s。我不知道为什么会被否决,这是正确的。为了让您的答案更清楚,请您添加I
和j
子列表中的参数做什么?