0
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

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • Your chose to use an iterative approach while he chose to use `map`. Your approach could be cleaned up, but I see nothing wrong with choosing iteration over `map` here. – user3483203 May 20 '18 at 02:15
  • Your solution also returns a list of tuples that you'll have to `' '.join` to get the same name strings. – miradulo May 20 '18 at 02:20
  • But doesn't Colt need to use something like this to access a dictionary within a list . list[0]['first] that is equal to the name rather first and last only. Plus my solution is wrong. Why? – John Snow May 20 '18 at 02:21
  • miradulo why wouldn't zip help? – John Snow May 20 '18 at 02:22
  • Note: you can create the tuple using just one loop, e.g. `for z in names: result.append((z['first'], z['last']))` but you can just `' '.join()` instead, e.g. `for z in names: result.append(' '.join([z['first'], z['last']]))` – AChampion May 20 '18 at 02:29
  • `full_names = [n["first"] + " " + n["last"] for n in names]` is the most optimal solution. Using `map` and unnecessary zipping of the lists is an overkill for such a simple thing. – zwer May 20 '18 at 02:32

3 Answers3

1

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]
    
spectras
  • 13,105
  • 2
  • 31
  • 53
0

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)]
0

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]
Waket Zheng
  • 5,065
  • 2
  • 17
  • 30