John Snow
John Snow

Reputation: 1

Differences in code when accessing a nested dictionary

def extract_full_name(names):

    firstname = []
    lastname = []
    for z in range(0,len(names)):
        firstname.append(names[z]['first'])
    for k in range(0,len(names)):
        lastname.append(names[k]['last'])

    return list(zip(firstname,lastname))

VS

def extract_full_name(l):
     return list(map(lambda val: "{} {}".format(val['first'], val['last']), l))

SO I am doing this course on udemy and it requires me to do something like this:

names = [{'first': 'Elie', 'last': 'Schoppik'}, {'first': 'Colt', 'last': 'Steele'}]
extract_full_name(names) # ['Elie Schoppik', 'Colt Steele']

What is the difference in my code and Colt's solution

Upvotes: 0

Views: 69

Answers (3)

spectras
spectras

Reputation: 13552

Let's build upon what you have done:

  1. In python, sequences are iterable with a for loop. When you don't need the index, don't count it:

    def extract_full_name(names):
        firstname = []
        lastname = []
        for item in names:
            firstname.append(item['first'])
        for item in names:
            lastname.append(item['last'])
        return list(zip(firstname,lastname))
    
  2. To simply generate a list out of another one, you may use a list comprehension:

    def extract_full_name(names):
        firstname = [item['first'] for item in names]
        lastname = [item['last'] for item in names]
        return list(zip(firstname,lastname))
    
  3. Since you iterate twice the same sequence we could also avoid the zip by combining as we go:

    def extract_full_name(names):
        return [(item['first'], item['last']) for item in names]
    
  4. Now, let's fix the mistake in your output: you output each full name as a 2-tuple containing two strings (the first name and the last name). Let's format them into a full name instead:

    def extract_full_name(names):
        return ['{} {}'.format(item['first'], item['last']) for item in names]
    

    That version is pretty much the one that confuses you, but it uses a list comprehension instead of map.

  5. [bonus] Since we use format, we could also use its rich syntax to access item's entries:

    def extract_full_name(names):
        return ['{name[first]} {name[last]}'.format(name=item) for item in names]
    

Upvotes: 1

Waket Zheng
Waket Zheng

Reputation: 6351

I would rather to do as follow:

names = [{'first': 'Elie', 'last': 'Schoppik'}, {'first': 'Colt', 'last': 'Steele'}]
fullnames = [f"{n.get('first', '')} {n.get('last', '')}" for n in names]

Upvotes: 0

Mantas Kandratavičius
Mantas Kandratavičius

Reputation: 1508

In both cases you will have to iterate through the names list in one way or another.

The way you do it is by iterating once to get all the first names and then iterating again to get all the last names - then you put the first name and the corresponding last name in a tuple and return a list of tuples.

The 2nd function iterates only once, and it does that using the map function. In the map function, there's a lambda function that will be applied for every item of the list. The lambda function takes a dictionary val from the list and puts first and last name in a string, separating them with a space:

a = "Hello"
b = "world!"
string = "{} {}".format(a, b)

string now equals to "Hello world!". This is repeated for every dictionary in the list where a is the first name and b is the last name. The map object is then converted to a list and returned.

The key difference in the output, is that you are returning a list of tuples, and not a list of strings. To fix that problem, modify the end of your function from this:

return list(zip(firstname,lastname))

to this:

return [" ".join(names) for names in zip(firstname,lastname)]

Upvotes: 0

Related Questions