Python Forum

Full Version: to find in dictionary given parameter 'name' and to output position
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
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.')
(Oct-03-2023, 04:32 PM)Pedroski55 Wrote: [ -> ]
if not Ergebnis == None:

(Oct-03-2023, 04:32 PM)Pedroski55 Wrote: [ -> ]
if telefonbook.get(akey) == None:

Programming recommendation from PEP8:


Quote:Comparisons to singletons like None should always be done with is or is not, never the equality operators.

Quote:Use is not operator rather than not ... is. While both expressions are functionally identical, the former is more readable and preferred:

# Correct:
if foo is not None:
# Wrong:
if not foo is None:
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. Shy

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.
Pages: 1 2