簡體   English   中英

如何使用字典來實現“switch/case”,其中評估值可能會失敗?

[英]How can I use a dictionary to implement "switch/case", where evaluating the values could fail?

我正在解決以下問題: https://www.codewars.com/kata/5266876b8f4bf2da9b000362/train/python

實現一個 function likes:: [String] -> String,它必須接受輸入數組,包含喜歡某個項目的人的姓名。 它必須返回示例中所示的顯示文本:

 likes([]) # must be "no one likes this" likes(["Peter"]) # must be "Peter likes this" likes(["Jacob", "Alex"]) # must be "Jacob and Alex like this" likes(["Max", "John", "Mark"]) # must be "Max, John and Mark like this" likes(["Alex", "Jacob", "Mark", "Max"]) # must be "Alex, Jacob and 2 others like this"

這是我的解決方案:

def likes(names):
    length = len(names)
    switcher = {
        0: "no one likes this",
        1: f"{names} likes this", 
        2: f'{names[0]} and {names[1]} like this', 
        3: f'{names[0]}, {names[1]} and {names[2]} like this', 
        4: f'{names[0]}, {names[1]} and ({length} - 2) others like this'
    }
    return switcher.get(length)

但是,如果我使用包含少於 2 個名稱的列表來調用它,我會得到 IndexError:

2: f'{names[0]} and {names[1]} like this',
IndexError: list index out of range

為什么我不能這樣做,或者如果我可以,我該如何解決?

 length = len(names) switcher = { 0: "no one likes this", 1: f"{names} likes this", 2: f'{names[0]} and {names[1]} like this', 3: f'{names[0]}, {names[1]} and {names[2]} like this', 4: f'{names[0]}, {names[1]} and ({length} - 2) others like this' } return switcher.get(length)

在這里,大概您期望它的行為類似於這樣的鏈式if / elif語句:

if length == 0:
    return "no one likes this"
elif length == 1:
    return f"{names} likes this"
elif length == 2:
    return f'{names[0]} and {names[1]} like this'

依此類推,其中每個返回表達式僅在相應條件為真時才被評估。

但事實並非如此。 字典switcher是在length起作用之前完全構建的。 因此,當傳遞少於 2 個元素的列表names時,仍會評估 2、3 和 4 個元素的值,這會引發IndexError ,因為names[1]甚至names[0]都不存在。

解決這個問題最清晰的方法就是使用if / elif / else


可以創建一個包含函數的字典,這些函數又返回格式化的字符串。

“else”的情況不應該在4鍵中,而是對應於.get()返回的默認值:

def likes(names):
    length = len(names)
    switcher = {
        0: lambda _: "no one likes this",
        1: lambda n: f"{n[0]} likes this", 
        2: lambda n: f'{n[0]} and {n[1]} like this', 
        3: lambda n: f'{n[0]}, {n[1]} and {n[2]} like this'
    }
    formatter = switcher.get(
        length,
        lambda n: f'{n[0]}, {n[1]} and ({length} - 2) others like this'
    )
    return formatter(names)

請注意,在1一種情況下,您應該使用names[0] ,而不是names

這里的問題是字典在定義switcher時嘗試創建其所有元素,並且在lenght <= 2時失敗,因為第三個元素( names[2] )不存在,因此會引發錯誤

暫無
暫無

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

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