问题
I've achived these two things.
Find all possible sublists of a list in given range
(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 :[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 becomeX = [66, 5082, 447216, 77, 6776, 88]`
Now, the minimum of the above list, which is
min(X)
i.e66
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 ?
Thanks in advance !
EDIT :
Got it. But, If there is more than one such possible sublist with the same minimum product,
- I need the longest sub list range
(i,j)
- If there are still more than one sublists with the same "longest sub range", I need to print the sub-interval which has the lowest start index.
Consider this list 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)'
.
Both sub list range = 0 [ (0-0) and (4-4) ]
In this case i need to 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 !
回答1:
First, given the list and the index range, we can get the sublist A[i : j + 1]
[66, 77, 88]
For positive integers a
and b
, a * b
is no less than a
or 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])
回答2:
For generating the sublists, it is as simple as two nested for
loops in a list comprehension:
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)
)
回答3:
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.
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:
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.
回答4:
#EDIT: Quick Solution:
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
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.
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.
We'll use itertools.combinations to solve this. We can do this in 3 steps.
Step1: Get the slice of the list
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:
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
So, we will use this to generate subsequences of length 1 to length equal to length of my_list
. We will get a list of tuples with each element being a subsequence.
Step-3 : Find min product of all possible combinations
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. Then we apply min()
function to get the minimum product out of the products_list
which will give us our answer.
回答5:
Take a look a 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.
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.
回答6:
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]]
来源:https://stackoverflow.com/questions/30820997/efficient-pythonic-way-of-finding-all-possible-sublists-of-a-list-in-given-ran