Hello!
Given ist the dictionary "telefonbook" with telefon-Nr. as the key, and with vorname, name, adress as the parameters to the keys.
I'm trying to write a programm which with the funktion "searchName" with an given name also all rest parameter printed.
What I doing wrong?:
telefonbook = {
'52307': {'vorname': 'Max', 'name': 'Mustermann', 'adress': 'poststr. 15'},
'25758': {'vorname': 'Thom','name': 'Swenson', 'adress': 'bethastr. 37'},
'01579': {'vorname': 'Jeff', 'name': 'Peters', 'adress': 'sportstr. 584'}
}
def searchName(telefonbook, name):
"""Durchsucht ein Adressbuch nach einem Namen.
Durchsucht die Dictionary-Objekte eines Adressbuchs, ob ein Name
in deren Werten vorkommt.
Arguments:
telefonbook (dict): Das Adressbuch, welches durchsucht werden soll
name (str): Der Name, nach dem gesucht wird
Returns:
dict: Ein Teiladressbuch mit den gefundenen Adressen und vornamen
"""
results = {}
for item in telefonbook.items():
person = item[1]
if name in person.values():
results[item[0]] = person
return results
ergebnis = searchName(telefonbook, 'Swenson')
print(ergebnis)
You ask what you are doing wrong.
The program gives a good result so in that sense nothing is wrong. It depends an what you want it to do. But there are some changes to consider.
First:
for item in telefonbook.items():
*.items() will deliver (a tuple of) two values at a time (a key and a value). But you assign it to one variable. It would make sense to assign it to two variables. Like this:
for telefon, person in telefonbook.items():
Second:
person = item[1]
This is not needed if you follow my first suggestion.
Third:
if name in person.values():
Here you make a list of the values of a person and you test if any of the values in this list is equal to the name you are looking for (it may also be the "vorname" or "address"). This may be what you want, but I have the feeling you are only interested if person["name"] equals the name you want to find. In that case it would be MUCH more efficient to do:
if person["name"] == name:
If you are confident there can be only one match, you could exit the search loop here and return from the function. If you want all the matches you do right in continuing the search.
So my suggestion of the function would be:
def searchName(telefonbook: dict, name: str) -> dict:
results = {}
for telefon, person in telefonbook.items():
if person["name"] == name:
results[telefon] = person
return results
Or you can use a comprehension.
def searchName(telefonbook, name):
return [entry["vorname"] for entry in telefonbook.values() if entry["name"] == name]
ergebnis = searchName(telefonbook, 'Swenson')
print(ergebnis)
And you could make a more generic tool.
def dictValueLookup(dictionary, match):
"""Return dictionary items that match(item) is True."""
return [item for item in dictionary.items() if match(item)]
ergebnis = dictValueLookup(telefonbook, lambda x: x[1]["name"] == "Swenson")
print(ergebnis)
But since the function is only one line long, you have to wonder if it is worth having a function at all.
ergebnis = [item for item in telefonbook.items() if item[1]["name"] == "Swenson"]
print(ergebnis)
Often there is more than 1 entry for a surname, you should perhaps think about that.
I don't think you really need to pass the dictionary to the function.
telefonbook = {
'52307': {'vorname': 'Max', 'name': 'Mustermann', 'adress': 'poststr. 15'},
'25758': {'vorname': 'Thom','name': 'Swenson', 'adress': 'bethastr. 37'},
'01579': {'vorname': 'Jeff', 'name': 'Peters', 'adress': 'sportstr. 584'},
'11112222': {'vorname': 'Dumb','name': 'Swenson', 'address': 'Gottlobstr. 99, Friedenau'}
}
def findName(someone):
#maybe there is more than 1 Swenson
results= []
for key in telefonbook.keys():
if telefonbook[key]['name'] == someone:
results.append(telefonbook[key])
# maybe the name ist nicht vorhanden
if len(results) == 0:
print(f'{someone} ist nicht im Telefonbuch.')
return None
else:
return results
person = input('Who you lookin\' for Hübscher? Bitte einen Familiennamen eingeben ... ')
Ergebnis = findName(person)
if not Ergebnis == None:
for E in Ergebnis:
print(E)
dict.get(key) returns None if the key is not in the dictionary. This is often very useful.
akey = '12345678'
if telefonbook.get(akey) == None:
print(f'The number {akey} is not in the Telefonbuch.')
Haha, funny how it works anyway!
I never used
is for anything. I just read
is has other uses apart from with None, but mainly it is reserved for None.
This from realpython.com
here.
Quote:02:22 To illustrate the difference between equality and identity, first, let’s take a look at a == b. This is True because the two strings have the same value.
02:32 They both say "This is a string", right? So they’re equal to one another.
02:36 But if you say a is b, you get False because a and b were declared separately from one another, right? So they’re technically separate objects even though they have the same value.
02:50 And you can check this by saying id(a) and id(b), and those are two different numbers, meaning they were instantiated at different times.
To conform with PEP, my bad Python is easily corrected:
def findName(someone):
#maybe there is more than 1 Swenson
results= []
for key in telefonbook.keys():
if telefonbook[key]['name'] == someone:
results.append(telefonbook[key])
# maybe the name ist nicht vorhanden
if len(results) == 0:
print(f'{someone} ist nicht im Telefonbuch.')
return "Nix da!"
else:
return results
person = input('Who you lookin\' for Hübscher? Bitte einen Familiennamen eingeben ... ')
Ergebnis = findName(person)
if not Ergebnis == "Nix da!":
for E in Ergebnis:
print(E)
Thank you all very much for helping and intuition!
Yes, what I wanted was: to print out all parameters from the corresponding line if I give the parameter 'name" belongs to the line.
I've let run the variant of Pedrosik55 and its run!
I'll consider all variants which you have written me, all Options are helpfull by learning in praxis.
ibreeden, deanhystad, buran - I'll work through your answers ('entry' corrsep PEP, etc.) , It'll take a little time.
Thank you!
I would write in such way:
telefonbook = {
'52307': {'vorname': 'Max', 'name': 'Mustermann', 'adress': 'poststr. 15'},
'25758': {'vorname': 'Thom','name': 'Swenson', 'adress': 'bethastr. 37'},
'01579': {'vorname': 'Jeff', 'name': 'Peters', 'adress': 'sportstr. 584'}
}
def searchName(telefonbook, name):
"""Durchsucht ein Adressbuch nach einem Namen.
results = {}
for item in telefonbook.items():
person = item[1]
if name in person.values():
results[item[0]] = person
return results
person = input('Who you lookin\' for Hübscher? Bitte einen Familiennamen eingeben ... ')
Ergebnis = searchName(person)
for E in Ergebnis:
print(E)
or last 3 lines f code even so:
person = input('Who you lookin\' for Hübscher? Bitte einen Familiennamen eingeben ... ')
Ergebnis = searchName(person)
print(Ergebnis)
I want to anderstand why it doesn't run...
Why are you doing:
for E in Ergebnis:
print(E)
?
Is 'Ergebnis' an list?
(Oct-05-2023, 12:13 AM)Liki Wrote: [ -> ]Is 'Ergebnis' an list?
Ergebnis is a dictionary. When you do:
for E in Ergebnis:
print(E)
... only the keys (telephone numbers) are printed. If you want to see all the data, you could do:
for E in Ergebnis.items():
print(E)
... the keys and the values (telephone numbers and person-data) will be printed.