简体   繁体   English

python`else`不能按预期工作

[英]python `else` doesn't work as expected

def greet(language):
    database = {'english': 'Welcome',
                'czech': 'Vitejte',
                'danish': 'Velkomst',
                'welsh': 'Croeso'}
    for k, v in database.items():
        if language == k:
            return v
        # else: return('Welcome')

print(greet('czech'))
> Vitejte

If I uncomment else: return('Welcome') (so if the greeting language is not in the list) I expect to receive 'Welcome' but it returns 'Welcome' no matter if I enter the existing or non-existing language. 如果我取消注释else: return('Welcome') (因此,如果问候语不在列表中),无论我输入现有的还是不存在的语言,我都希望收到“ Welcome”,但它会返回“ Welcome”。

I had also tried elif language =!= k but it appeared to work in the same unwanted fashion 我也尝试过elif language =!= k但它似乎以不想要的方式工作

You want this instead: 您想要这个:

def greet(language):
    database = {'english': 'Welcome',
                'czech': 'Vitejte',
                'danish': 'Velkomst',
                'welsh': 'Croeso'}
    for k, v in database.items():
        if language == k:
            return v

    # Return this only if none of the items matched.
    return('Welcome')

As your code currently stands, it only ever checks the first item in the dictionary. 就目前的代码而言,它只会检查字典中的第一项。 If that key matches, it returns the appropriate value. 如果该键匹配,则返回适当的值。 Otherwise, it returns "Welcome," but it never moves on to the second item. 否则,它将返回“ Welcome”,但它永远不会移至第二项。

In my code, it checks all of the items and returns the right value as soon as it finds a match. 在我的代码中,它检查所有项目,并在找到匹配项后立即返回正确的值。 Only if it fails to find a match does it return "Welcome." 仅当找不到匹配项时,它才会返回“欢迎”。

Incidentally, this is an even simpler version of the code: 顺便说一下,这是代码的更简单版本:

def greet(language):
    database = {'english': 'Welcome',
                'czech': 'Vitejte',
                'danish': 'Velkomst',
                'welsh': 'Croeso'}
    return database.get(language, 'Welcome')

dict.get lets you do a dictionary lookup and use a default value if the item is not found. dict.get允许您执行字典查找,如果找不到该项目,则使用默认值。

It's basically short-hand for this (but dict.get is preferred): 这基本上是dict.get方式(但是dict.get是首选):

if language in database:
    return database[language]
else:
    return 'Welcome'

See it like this, the for loop will enumerate over the items . 这样看, for循环将枚举item

Let's assume the first item the .items() fetches is 'english': 'Welcome' . 假设.items()提取的第一项是'english': 'Welcome' Now if the language is not English, then the if will fail, and so the else part is executed an 'Welcome' is returned. 现在,如果语言不是英语,则if将失败,因此执行else部分,并返回'Welcome' Only if the first item enumerated is indeed the correct language, your program will return that value. 仅当枚举的第一项确实是正确的语言时,程序才会返回该值。

Nevertheless you make things too complicated, you can use dict.get(..) with a fallback value : 不过,您会使事情变得过于复杂,可以使用具有后备值的 dict.get(..)

def greet(language):
    database = {'english': 'Welcome',
                'czech': 'Vitejte',
                'danish': 'Velkomst',
                'welsh': 'Croeso'}
    return database.get(language,'Welcome')

This will also boost performance: your original program had O(n) time complexity whereas a lookup on average on a dictionary is done in O(1) time. 这也将提高性能:您的原始程序具有O(n)的时间复杂度,而对字典的平均查找则需要O(1)的时间。

That's because the return statement when executed in the first branching to else hijacks control from the for , exiting the function. 这是因为return时,在第一分支来执行的语句else劫持控制for ,退出功能。 You can, for example, move the else as part of the for instead; 例如,您可以将else作为for一部分移动。 indicating 'Welcome' should only be returned when the for is exhausted cleanly : 表示'Welcome'时,只应返回for干净耗尽:

...
for k, v in database.items():
    if language == k:
        return v
else: 
    return 'Welcome'

Or use the dictionary's get method to return a default: 或使用字典的get方法返回默认值:

...
return database.get(lang, 'Welcome')

I have modified code and attached output as well: 我修改了代码并附加了输出:

def greet(language):
    database = {'english': 'Welcome',
                'czech': 'Vitejte',
                'danish': 'Velkomst',
                'welsh': 'Croeso'}
    for k in database.keys():

        if language == k:
            return database[k]

    return('Welcome')


print(greet('english'))
print(greet('czech'))
print(greet('welsher'))
print(greet('danish'))
print(greet('welsh'))
print(greet('hindi'))

Output : Welcome Vitejte Welcome Velkomst Croeso Welcome 输出:Welcome Vitejte Welcome Velkomst Croeso Welcome

Take a look at this SO post you will get an idea about what is the fastest way to check if a key is in dictionary. 看一下这篇SO帖子,您将了解什么是最快的方法来检查键是否在字典中。

So in your case I would say this is the fastest way to check 因此,就您而言,这是检查的最快方法

def greet(k):
    database = {'english': 'Welcome',
                'czech': 'Vitejte',
                'danish': 'Velkomst',
                'welsh': 'Croeso'}
    if k in database:
        return(database[k])
    else:
        return('Welcome')
print(greet('welsh'))

output: 输出:

Croeso

But for: 但对于:

def greet(k):
    database = {'english': 'Welcome',
                'czech': 'Vitejte',
                'danish': 'Velkomst',
                'welsh': 'Croeso'}
    if k in database:
        return(database[k])
    else:
        return('Welcome')
print(greet('tamil'))

output: 输出:

Welcome

Whatever you have mentioned is expected behaviour only , why because DICTIONARY is a un-ordered collection of objects. 无论您提到什么,都是预期的行为,这是为什么,因为DICTIONARY是对象的无序集合。

whenever you do dict.items() it may iterate in any order,consider your example itself: 每当您执行dict.items()时,它都可以以任何顺序进行迭代,请考虑您的示例本身:

def greet(language):
database = {'english': 'Welcome','czech': 'Vitejte','danish': 'Velkomst',
            'welsh': 'Croeso'}

for k, v in database.items():
    print "k,v :",k,v       --> it may print you in any order 

output:
       Combination 1:

       1) english': 'Welcome 2) danish': 'Velkomst 3) czech': 'Vitejte
       4) welsh': 'Croeso

       Combination 2:

       1) welsh': 'Croeso  2)  english': 'Welcome 3) czech': 'Vitejte
       4) danish': 'Velkomst

       and few more combinations will yield .....

So, In your example your first iteration is other than czech that is the reason your code is always returning Welcome . 因此,在您的示例中,您的第一个迭代不是czech ,这是代码始终返回Welcome的原因。

To avoid that, either you can go with dict.get() or simply track a variable as below: 为了避免这种情况,您可以使用dict.get()或仅跟踪一个变量,如下所示:

def greet(language):
var = 0                            -> intialized var with 0
database = {'english': 'Welcome',
            'czech': 'Vitejte',
            'danish': 'Velkomst',
            'welsh': 'Croeso'}
for k, v in database.items():

    if k == language:
        var = 1                    -> if enterd in loop assign var = 1 
        return v

if (var != 1):
   return('Welcome')               -> if above compa'ion fails returns welcome

print(greet('czech')) 打印(问候('捷克'))

Vitejte 维捷特

print(greet('zabcczech')) 打印(问候('zabcczech'))

Welcome 欢迎

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM