0

I have a list of dictionaries like this. Some data contains both first name and last name, and some data only includes first name:

['info': {'id': 'abc', 'age':23, 'firstname':'tom', 'lastname':'don', 'phone': 1324}]
['info': {'id': 'cde', 'age':24, 'firstname':'sara', 'lastname':'man', 'phone': 1324}]
['info': {'id': 'cdd', 'age':22, 'firstname':'sam', 'phone': 1324}]
['info': {'id': 'fff', 'age':25, 'firstname':'mary', 'phone': 1324}]

There is a library and function that retrieves data based on its id. I need to get the data and make a dataset. 'Lastname' is more important data. In case when 'lastname' does not exist, I want to get 'firstname', so I wrote a code as below and it does not work.

ids = ['abc', 'cde', 'cdd', 'fff']

list = [] 
for id in ids:
    data = library.function(id)
    if data['info']['lastname'] in data['info']:
        new_list1 = [data['info']['id'], data['info']['lastname'], data['info']['phone']]
        list.append(new_list1)
    else:
        new_list2 = [data['info']['id'], data['info']['firstname'], data['info']['phone']]
        list.append(new_list2)
print(list)

I still get keyError:

KeyError: 'lastname'  

How shall I fix the code? Or is there any tips for a case like this?

Sunderam Dubey
  • 1
  • 11
  • 20
  • 40
hyeppy
  • 79
  • 1
  • 7
  • 1
    That doesn't look like a list of dictionaries... In fact it doesn't look like valid Python at all. Can you clarify your data structure, please? – CrazyChucky Feb 05 '22 at 03:52
  • I simplified Dto that I got from API. Sorry for the confusion. – hyeppy Feb 05 '22 at 03:58

3 Answers3

2

The most common or easiest way to solve your problem would be Exception Handling. The code that checks for the first name should be inside the try block. What this does is if the computer comes across the exception, instead of firing the exception it executes the Except block. You can get more information with a simple search.

Code:

try:
    if data['info']['lastname'] in data['info']:
        new_list1 = [data['info']['id'], data['info']['lastname'], data['info']['phone']]
        list.append(new_list1)
except KeyError:
    new_list2 = [data['info']['id'], data['info']['firstname'], data['info']['phone']]
        list.append(new_list2)

Of course you can also just replace:

if data['info']['lastname'] in data['info']:

with:

if 'lastname' in data['info'].keys():

This checks if the key 'lastname' and then executes the last name search

Anshumaan Mishra
  • 1,349
  • 1
  • 4
  • 19
  • 2
    You also don't need the `.keys()`; checking whether something is `in` a dictionary automatically checks the keys. – CrazyChucky Feb 05 '22 at 04:05
1

Best way is to check if the key exists rather than if a value exists in the key.

Instead of

if data['info']['lastname'] in data['info']:

Try this:

if 'lastname' in data['info']:

1

This line:

if data['info']['lastname'] in data['info']:

...doesn't do what you think it does. It attempts to actually retrieve the value stored at data['info']['lastname'], and then see if that is contained in data['info']. What you want instead is:

if 'lastname' in data['info']:

...which checks if the string 'lastname' is one of the keys in data['info'].

A couple of other notes:

  • It's bad practice to shadow names of builtins, like list and id.
  • You don't seem to be accessing any other part of data besides data['info'], so you can simplify your code a bit by assigning just that part to your variable.
  • In this case I'd recommend using the dictionary's get method, which can retrieve a value if the requested key exists, but otherwise return a default value.

With all that handled, your code could look something like this:

ids = ['abc', 'cde', 'cdd', 'fff']

people = [] 
for person_id in ids:
    data = library.function(person_id)['info']
    # Assigns name to the lastname if it exists in the dict, or else
    # assigns it to firstname
    name = data.get('lastname', data['firstname'])
    people.append([data['id'], name, data['phone']])

print(people)
CrazyChucky
  • 3,263
  • 4
  • 11
  • 25