簡體   English   中英

需要在列表列表中找到最大值

[英]Need to find a maximum in a list of lists

我在Peter Wentworth的“如何像計算機科學家一樣思考:學習Python 3,第3版”中找到了這個問題。 我也在下面添加了他們的解決方案。

我簡單的遞歸函數產生錯誤的輸出

def maximum_in_list(L):
    '''Finds the maximum value from L which is a List_of_List'''
    item=0
    for i in L:
        if type(i)==list:
            item=maximum_in_list(i)
        elif i>item:
            item=i
    return item

print(maximum_in_list([9,18,99,7,4,21,[3,5,[27,57,92],7,76],32,4]))
print(maximum_in_list([2, 9, [1, 13], 8, 6]))
print(maximum_in_list([2, [[100, 7], 90], [1, 13], 8, 6])) #Here the problem occurs
print(maximum_in_list([[[13, 7], 90], 2, [1, 100], 8, 6]))

圖書代碼產生了正確的代碼,但是為什么需要標記?

def r_max(nxs):
   largest=None
   first_time=True
   for e in nxs:
       if type(e)=type([]):
           val=r_max(e)
       else:
           val=e
       if first_time or val>largest:
           largest=val
           first_time=False
   return largest

盡管可以產生正確的結果,但我無法理解標志的要求。

您的遞歸方法存在問題。 簡單的解決方法是:

item = max(item, maximum_in_list(i))

更新后的代碼如下所示:

def maximum_in_list(L):
    '''Finds the maximum value from L which is a List_of_List'''
    item=0
    for i in L:
        if type(i)==list:
            item=max(item, maximum_in_list(i))
        elif i>item:
            item=i
    return item

print(maximum_in_list([9,18,99,7,4,21,[3,5,[27,57,92],7,76],32,4]))
print(maximum_in_list([2, 9, [1, 13], 8, 6]))
print(maximum_in_list([2, [[100, 7], 90], [1, 13], 8, 6])) #Here the problem occurs
print(maximum_in_list([[[13, 7], 90], 2, [1, 100], 8, 6]))

第一次標記用於防止將None值與整數進行比較。 如果在沒有first_time檢查的情況下進行比較,則會導致類型錯誤。

這是一個更緊湊的遞歸解決方案,它使用生成器表達式和內置的max函數。 它可以正確處理負值,並且還可以處理非數值數據。 但是,如果將包含無法比較的項目(例如數字和字符串)的列表傳遞給它,則會引發TypeError

def r_max(lst):
    return max(r_max(u) if isinstance(u, list) else u for u in lst)

# test

data = (
    [9,18,99,7,4,21,[3,5,[27,57,92],7,76],32,4],
    [2, 9, [1, 13], 8, 6],
    [2, [[100, 7], 90], [1, 13], 8, 6],
    [[[13, 7], 90], 2, [1, 100], 8, 6],
    [[[-13, -7], -90], -2, [-1, -100], -8, -6],
    ['abc', 'd', ['ef', 'ghi', ['jkl', 'zzz'], 'xy', 'z']],
)

for lst in data:
    print(lst)
    print(r_max(lst))

產量

[9, 18, 99, 7, 4, 21, [3, 5, [27, 57, 92], 7, 76], 32, 4]
99
[2, 9, [1, 13], 8, 6]
13
[2, [[100, 7], 90], [1, 13], 8, 6]
100
[[[13, 7], 90], 2, [1, 100], 8, 6]
100
[[[-13, -7], -90], -2, [-1, -100], -8, -6]
-1
['abc', 'd', ['ef', 'ghi', ['jkl', 'zzz'], 'xy', 'z']]
zzz

這是您的功能的巧妙解決方案:

def maximum_in_list(L):
    '''Finds the maximum value from L which is a List_of_List'''
    item = -float('inf')
    for i in L:
        if isinstance(i, list):
            i = maximum_in_list(i)  # see remark
        item = max(item, i)
    return item

備注:

i是一個list ,可以將其重新分配到該list的最大值( 遞歸 ),這樣您就不必使用過多的if語句。


print(maximum_in_list([9,18,99,7,4,21,[3,5,[27,57,92],7,76],32,4]))  # ->  99
print(maximum_in_list([2, 9, [1, 13], 8, 6]))                        # ->  13
print(maximum_in_list([2, [[100, 7], 90], [1, 13], 8, 6]))           # -> 100
print(maximum_in_list([[[13, 7], 90], 2, [1, 100], 8, 6]))           # -> 100

該標志確保每次都不將item變量重置為0,從而產生有問題的輸出。 您的代碼存在以下問題:每當調用該函數的子列表時,它都會重置item變量,然后將最大值與0(而不是舊的最大值)進行比較。

在有問題的輸入中,如果更改6和100的位置,則將獲得正確的輸出,因為到那時為止,最后一個子列表已經處理完畢。 如果在現在更改為100(位置6)之后添加另一個子列表,那么您將再次出現此問題。

暫無
暫無

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

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