簡體   English   中英

在子列表上使用 min 和 max 並創建一個列表而不使用外部的“for循環”減少 function

[英]Using min and max on sublists and creating a list without using "for loop" outside reduce function

from functools import reduce
for _ in range(int(input())):
    N = int(input())
    l1 = list(map(int,input().split()))
    def powerset(lst):
        return reduce(lambda result, x: result + [subset + [x] for subset in result],
                      lst, [[]])
        
    #https://stackoverflow.com/questions/1482308/how-to-get-all-subsets-of-a-set-powerset

    lst = (powerset(l1))
    print(lst)
    ivlst = []
    
    for i in range(1, len(lst)):
        ivlst.append((min(lst[i])*max(lst[i])))
    print(min(ivlst), end=" ")
    print(max(ivlst))

樣本輸入:

2
2
2 2
3
5 0 9

樣品 output:

4 4
0 81

上面的代碼執行以下操作:

  1. 它將輸入作為 N,其中 N 是列表中的元素數。
  2. 然后它將輸入作為列表的元素。
  3. 然后它創建一個名為 powerset 的 function,它以一個列表作為參數並返回該列表的所有子集。
  4. 然后它調用 powerset function 上的 reduce function,列表作為第一個參數,空列表作為第二個參數。
  5. 減少 function 將返回列表列表。
  6. ivlst 變量用於存儲子集的最小值和最大值。
  7. 然后它遍歷從 1 到列表長度的范圍。
  8. 對於每次迭代,它將子集的最小值和最大值的乘積附加到 ivlst 列表中。
  9. 最后,它打印 ivlst 列表的最小值和最大值。

時間復雜度為 O(2^n),其中 n 是給定集合中元素的數量。

我需要一種不使用for 循環來獲取所有子列表的最小值和最大值的方法,而是我需要從 powerset function 本身獲取一個包含所有子列表的最小值和最大值的乘積的列表,如 output

您的powerset function 的等效代碼如下:

from itertools import islice

def powerset(lst):
    ret = [[]]
    for elem in lst:
        for subset in islice(ret, len(ret)):
            ret.append(subset + [elem])
    return ret

我們不再在內循環中構建和記錄剩余的子集,而只記錄子集的最小值和最大值,這樣我們的運行成本就會大大降低(從O(n * 2^n)O(2^n) ,因為冪集的生成算法不會比O(2^n)快,並且為每個子集計算的最小值和最大值為O(n) ):

from itertools import islice

def powerset_extremum(lst):
    ret = [(float('inf'), float('-inf'))]
    for elem in lst:
        for min_, max_ in islice(ret, len(ret)):
            ret.append((min(min_, elem), max(max_, elem)))
    return ret

簡單測試:

>>> powerset([2, 1, 4, 3])
[[],
 [2],
 [1],
 [2, 1],
 [4],
 [2, 4],
 [1, 4],
 [2, 1, 4],
 [3],
 [2, 3],
 [1, 3],
 [2, 1, 3],
 [4, 3],
 [2, 4, 3],
 [1, 4, 3],
 [2, 1, 4, 3]]
>>> powerset_extremum([2, 1, 4, 3])
[(inf, -inf),
 (2, 2),
 (1, 1),
 (1, 2),
 (4, 4),
 (2, 4),
 (1, 4),
 (1, 4),
 (3, 3),
 (2, 3),
 (1, 3),
 (1, 3),
 (3, 4),
 (2, 4),
 (1, 4),
 (1, 4)]

然后你可以很容易地得到它們的乘法:

>>> from itertools import starmap, islice
>>> from operator import mul
>>> list(starmap(mul, islice(powerset_extremum([2, 1, 4, 3]), 1, None)))
[4, 1, 2, 16, 8, 4, 4, 9, 6, 3, 3, 12, 8, 4, 4]

我知道這不符合您不使用 for 循環的要求,但顯然比在獲取電源集后通過一些內置函數消除顯式 for 循環要快得多。

您可以最大化powerset function 的生產,事實上,Python itertools頁面正好有一個powerset配方:

def powerset(iterable):
    "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
    s = list(iterable)
    return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))

或者您可以通過以下方式實現:

from more_itertools import powerset

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM