Reputation: 620
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.
I had also tried elif language =!= k
but it appeared to work in the same unwanted fashion
Upvotes: 0
Views: 149
Reputation: 143
Whatever you have mentioned is expected behaviour only , why because DICTIONARY is a un-ordered collection of objects.
whenever you do dict.items() it may iterate in any order,consider your example itself:
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.
To avoid that, either you can go with dict.get() or simply track a variable as below:
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'))
Welcome
Upvotes: 0
Reputation: 2642
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 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
Upvotes: 0
Reputation: 93
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
Upvotes: 0
Reputation: 476547
See it like this, the for
loop will enumerate over the items.
Let's assume the first item the .items()
fetches is '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. 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:
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.
Upvotes: 6
Reputation: 78536
That's because the return
statement when executed in the first branching to else
hijacks control from the for
, exiting the function. You can, for example, move the else
as part of the for
instead; indicating 'Welcome'
should only be returned when the for
is exhausted cleanly:
...
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:
...
return database.get(lang, 'Welcome')
Upvotes: 3
Reputation: 60133
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.
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.
It's basically short-hand for this (but dict.get
is preferred):
if language in database:
return database[language]
else:
return 'Welcome'
Upvotes: 7