简体   繁体   English

在给定范围内找到列表的所有可能子列表的高效和Pythonic方法以及在将所有元素相乘后的最小乘积?

[英]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. 我已经完成了这两件事。

  1. 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] 
  2. 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, 但是,如果有多个这样的可能子列表具有相同的最小产品,

  1. I need the longest sub list range (i,j) 我需要最长的子列表范围(i,j)
  2. 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) . 考虑这个列表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 . 对于正整数aba * b不小于ab 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.

相关问题 具有所有子列表变体的单列表的Pythonic方式 - Pythonic way of single list with all variations of sublists 比较列表中所有相邻元素的Pythonic方法 - Pythonic way of comparing all adjacent elements in a list 给定分组元素列表时,查找 hash 的所有可能排列 - Finding all possible permutations of a hash when given list of grouped elements 查找列表的所有可能的子列表 - Find all possible sublists of a list 什么是Pythonic方法来获取两个列表元素的所有可能组合的元组列表? - What is a Pythonic way to get a list of tuples of all the possible combinations of the elements of two lists? 用Python方式表示“如果列表1中的所有元素也存在于列表2中” - Pythonic way of saying “if all of the elements in list 1 also exist in list 2” 什么是确保列表中所有元素不同的最pythonic方法? - What's the most pythonic way to ensure that all elements of a list are different? 查找给定图的所有完整子图的有效方法(Python)? - Efficient way for finding all the complete subgraphs of a given graph (Python)? 用它们所有可能组合的 2 位数字随机填充列表,以便列表元素的总和给出一个给定的数字 - Fill a list randomly with 2 digits of all possible combinations of them so that the sum of the elements of the list gives a given number 获取列表的所有可能的有序子列表 - Get all possible ordered sublists of a list
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM