簡體   English   中英

如何使 Python 代碼更高效?

[英]How can I make Python code more efficient?

新手來了我有這個代碼,它顯示達到某個數字的所有可能的總和。 但是它的復雜度太高,當數字太高時需要太長時間。 我怎樣才能把它重構為更簡單的東西?

import itertools

def combos(n):

    result = []
    for i in range(n,0,-1):
        for seq in itertools.combinations_with_replacement(range(1,n+1), i):
            if sum(seq) == n:
                seq = list(seq)
                result.append(seq)
    return(result)

combos(4)

輸出:

[[1,1,1,1],[1,1,2],[1,3],[2,2],[4]]

遞歸版本可能是這樣的:

def combinations_max_sum(sum_max, i_max=None):

    if sum_max == 0:
        return [()]

    if not i_max or i_max > sum_max:
        i_max = sum_max

    combinations = [(i, *right_part)
                    for i in range(i_max, 0, -1)
                    for right_part in combinations_max_sum(sum_max-i, i_max=i)]

    return combinations

測試:

print(combinations_max_sum(4)) # [(4,), (3, 1), (2, 2), (2, 1, 1), (1, 1, 1, 1)]
print(combinations_max_sum(4, i_max=1)) # [(1, 1, 1, 1)]
print(combinations_max_sum(5))
# [(5,), (4, 1), (3, 2), (3, 1, 1), (2, 2, 1), (2, 1, 1, 1), (1, 1, 1, 1, 1)]

分解問題的想法:一組組合可以寫成一個數字,該數字與所有組合的總和為n減去第一個數字。

不處理重復的更簡單的代碼可能是這樣的:

def combinations_with_repetition(n):

    if n == 0:
        return [()]

    combinations = [(i, *right_part)  # concatenation
                    for i in range(1, n+1)  # for all possible first number 
                    for right_part in combinations_with_repetition(n-i)]
                    # ^ all possible combinations
                    #   given the first number i

    return combinations

這使:

combinations_with_repetition(3)
# [(1, 2), (1, 1, 1), (2, 1), (3,)]

(1, 2)(2, 1)類似,為了防止這種情況,添加了i_max參數(參見第一個函數)。 這里的想法是始終按降序排列。 右邊的數字總是等於或小於左邊的數字。 這個最大數字作為參數傳遞,循環從它開始,而不是要求的總和。

暫無
暫無

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

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