[英]Efficient & Pythonic way of finding all possible sublists of a list in given range and the minimum product after multipying all elements in them?
I've achived these two things. 我已经完成了这两件事。
Find all possible sublists of a list in given range (i ,j)
. 查找给定范围
(i ,j)
列表的所有可能的子列表。
A = [ 44, 55, 66, 77, 88, 99, 11, 22, 33 ] Let, i = 2 and j = 4
Then, Possible sublists of the list "A"
in the given range (2,4)
is : 然后,给定范围
(2,4)
列表"A"
可能子列表是:
[66], [66,77], [66,77,88], [77], [77,88], [88]
And, minimum of the resultant product after multipying all the elements of the sublists: 并且,在乘以子列表的所有元素之后,最终产品的最小值:
So, the resultant list after multiplying all the elements in the above sublists will become 因此,在乘以上述子列表中的所有元素之后的结果列表将变为
X = [66, 5082, 447216, 77, 6776, 88]`
Now, the minimum of the above list, which is min(X)
ie 66
现在,上面列表的最小值,即
min(X)
即66
My Code : 我的代码 :
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)
My Question: 我的问题:
This code is taking more time to get executed for the Larger Lists and Larger Ranges ! 此代码花费更多时间来执行更大的列表和更大的范围!
Is there any possible "Pythonic" way of reducing the time complexity of the above code ? 是否有任何可能的“Pythonic”方法来减少上述代码的时间复杂度?
Thanks in advance ! 提前致谢 !
EDIT : 编辑:
Got it. 得到它了。 But, If there is more than one such possible sublist with the same minimum product,
但是,如果有多个这样的可能子列表具有相同的最小产品,
(i,j)
(i,j)
Consider this list A = [2, 22, 10, 12, 2]
if (i,j) = (0,4)
. 考虑这个列表
A = [2, 22, 10, 12, 2]
(i,j) = (0,4)
A = [2, 22, 10, 12, 2]
if (i,j) = (0,4)
。
There is a tie. 有一个平局。
Min product = 2
with two possibilities '(0,0)' and '(4,4)'
. Min product = 2
有两种可能性'(0,0)' and '(4,4)'
。
Both sub list range = 0 [ (0-0) and (4-4) ]
子列表范围= 0
[ (0-0) and (4-4) ]
In this case i need to print (minproduct, [sublist-range])
= 2, [0,0]
在这种情况下我需要
print (minproduct, [sublist-range])
= 2, [0,0]
Tried using dictionaries, It works for some inputs but not for all ! 尝试使用词典,它适用于一些输入,但不适用于所有! How to do this 'efficiently' ?
如何“有效”地做到这一点?
Thank you ! 谢谢 !
First, given the list and the index range, we can get the sublist A[i : j + 1]
首先,给定列表和索引范围,我们可以得到子列表
A[i : j + 1]
[66, 77, 88]
For positive integers a
and b
, a * b
is no less than a
or b
. 对于正整数
a
和b
, a * b
不小于a
或b
。 So you don't need to do multiplying, it's not possible that multiplying of two or more elements has a smaller result. 所以你不需要进行乘法运算,两个或多个元素相乘的结果不可能更小。 The minimum of this list is the minimum of all the multiplying results.
这个列表的最小值为所有的乘法结果的最低。
So the result is: 结果是:
min(A[i : j + 1])
For generating the sublists, it is as simple as two nested for
loops in a list comprehension: 为了生成子列表,它就像列表解析中的两个嵌套
for
循环一样简单:
def sublists(l,i,j):
return [l[m:n+1] for m in range(i,j+1) for n in range(m,j+1)]
example: 例:
>>> sublists(A,2,4)
[[66], [66, 77], [66, 77, 88], [77], [77, 88], [88]]
For finding the minimum product: 寻找最低产品:
>>> min(map(prod, sublists(A,2,4)))
66
(you import prod
from numpy
, or define it as def prod(x): return reduce(lambda i,j:i*j,x)
) (你从
numpy
导入prod
,或者将它定义为def prod(x): return reduce(lambda i,j:i*j,x)
)
The accepted answer is correct for all positive ints as you cannot multiply the smallest element by any number and get a smaller result. 所接受的答案对于所有正整数都是正确的,因为您不能将最小元素乘以任何数字并得到较小的结果。 It might make more sense if you were getting all the slices greater than length 1.
如果您获得的所有切片大于长度1,则可能更有意义。
If you were going to calculate it then you could use itertools.islice
to get each slice and get the min using a generator expression: 如果你要计算它,那么你可以使用
itertools.islice
获取每个切片并使用生成器表达式获取min:
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
If for i = 0 and j = 4 you considered (44, 55, 66, 88)
a legitimate slice then you would need to use itertools.combinations. 如果对于i = 0和j = 4,您认为
(44, 55, 66, 88)
44,55,66,88 (44, 55, 66, 88)
是合法切片,那么您将需要使用itertools.combinations。
#EDIT: Quick Solution: #EDIT:快速解决方案:
min(A[i:j+1])
Since all the numbers are positive integers, and you want to find the minimum product of all possible sublists of A[i:j+1]
list 由于所有数字都是正整数,并且您想要找到
A[i:j+1]
列表的所有可能子列表的最小乘积
slice, it will also contain sublists of length 1. The minimum products of all such sublists will be lowest number among the A[i:j+1]
slice. 切片,它还将包含长度为1 的子列表。所有这些子列表的最小乘积将是
A[i:j+1]
切片中的最小数字。
Another Solution: 另一种方案:
The below method will be useful when you need to find the maximum product of sublists or you need all the possible combinations of A[i:j+1]
list slice. 当您需要查找子列表的最大乘积或需要
A[i:j+1]
列表切片的所有可能组合时,以下方法将非常有用。
We'll use itertools.combinations to solve this. 我们将使用itertools.combinations来解决这个问题。 We can do this in 3 steps.
我们可以分3步完成。
Step1: Get the slice of the list 第1步:获取列表的切片
my_list = A[i:j+1]
This will give us the slice to work on. 这将为我们提供切实的工作。
my_list = A[2:5]
my_list
[66, 77, 88]
Step-2 Generate all possible combinations: 步骤2生成所有可能的组合:
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.combinations returns r length subsequences of elements from the input iterable
iterools.combinations返回输入iterable中元素的r个子序列
So, we will use this to generate subsequences of length 1 to length equal to length of my_list
. 因此,我们将使用它来生成长度为1到长度等于
my_list
长度的子my_list
。 We will get a list of tuples with each element being a subsequence. 我们将得到一个元组列表,每个元素都是一个子序列。
Step-3 : Find min product of all possible combinations 第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
After getting the subsequences, we apply list comprehension along with reduce()
to get the list of products for all the subsequences in my_combinations
list. 获取子序列后,我们将列表理解与
reduce()
一起应用,以获取my_combinations
列表中所有子序列的产品列表。 Then we apply min()
function to get the minimum product out of the products_list
which will give us our answer. 然后我们应用
min()
函数从products_list
获取最小产品,这将给出我们的答案。
Take a look a itertools.combinations()
看看
itertools.combinations()
https://docs.python.org/3/library/itertools.html#itertools.combinations https://docs.python.org/3/library/itertools.html#itertools.combinations
Call it passing the sublist, in a loop, with the other parameter varying from 1 to the length of the sublist. 称它为循环中的子列表,其他参数从1到子列表的长度不等。
It will definitely take "more time to get executed for the Larger Lists and Larger Ranges", i think that's inevitable. 这肯定需要“更多的时间来为更大的名单和更大的范围执行”,我认为这是不可避免的。 But might be much faster than your approach.
但可能比你的方法快得多。 Measure and see.
测量并看到。
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])
[[], [10], [10, 20], [20], [10, 30], [20, 30], [30], [10, 20, 30]]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.