How to select only last names?

If you look at the documentation for the pop method,

Remove the item at the given position in the list, and return it. If no index is specified, a.pop() removes and returns the last item in the list.

For example,

x = [1, 4, 6, 8, 34]
y = x.pop()

print(y) # 34
print(x) # [1, 4, 6, 8]

# The popped/removed element is returned by the pop method.
# The original array is mutated.

One line assuming you split author_names correctly

author_last_names = [name.split(' ')[-1] for name in author_names]

I used both .split() and .pop() in a function to accomplish this task, I took advantage of the returning property of .pop() to store the last name. This is the function:

def last_names(authors):
last_names_list =
for author in authors:
splitted_author = author.split(" ")
last_name = splitted_author.pop()
last_names_list.append(last_name)
return last_names_list

Hey man, thank you so much. This was quite helpful

1 Like

this was the first problem I ever got stuck while learning python. it was very confusing!

Here’s what I came up with

author_last_names = [author_names[i].split()[1] for i in range(len(author_names))]

Do we really need to index this stuff? The values are exposed and accessible without index reference.

>>> authors = "Audre Lorde,Gabriela Mistral,Jean Toomer,An Qi,Walt Whitman,Shel Silverstein,Carmen Boullosa,Kamala Suraiyya,Langston Hughes,Adrienne Rich,Nikki Giovanni"
>>> [x.split()[-1] for x in authors.split(',')]
['Lorde', 'Mistral', 'Toomer', 'Qi', 'Whitman', 'Silverstein', 'Boullosa', 'Suraiyya', 'Hughes', 'Rich', 'Giovanni']
>>> 

Going down the rabbit hole…

>>> import re
>>> authors = "Audre Lorde, Gabriela Mistral, Jean Toomer, An Qi,Walt Whitman, Shel Silverstein, Carmen Boullosa, Kamala Suraiyya, Langston Hughes, Adrienne Rich, Nikki Giovanni"
>>> [x.split()[-1] for x in re.split(r'[(,)|(,*)]', authors)]
['Lorde', 'Mistral', 'Toomer', 'Qi', 'Whitman', 'Silverstein', 'Boullosa', 'Suraiyya', 'Hughes', 'Rich', 'Giovanni']
>>>

Not that it proves anything, if in fact, nothing, it’s a rabbit hole. Descend at one’s own peril or benefit, as it were.

My own concern was the whitespace potentially following the comma but it seems Python has worked that out and strips it from the proceeds.

>>> authors = "Audre Lorde, Gabriela Mistral, Jean Toomer, An Qi, Walt Whitman, Shel Silverstein, Carmen Boullosa, Kamala Suraiyya, Langston Hughes, Adrienne Rich, Nikki Giovanni"
>>> [x.split()[0] for x in authors.split(',')]
['Audre', 'Gabriela', 'Jean', 'An', 'Walt', 'Shel', 'Carmen', 'Kamala', 'Langston', 'Adrienne', 'Nikki']
>>> 

I’m blown away by having taken this long to discover it. Dang!


Going further down…

By only the slightest turn of phrase we can go from a list to a set to dictionary. No magic involved, just syntax.

>>> authors = "Audre Lorde, Gabriela Mistral, Jean Toomer, An Qi, Walt Whitman, Shel Silverstein, Carmen Boullosa, Kamala Suraiyya, Langston Hughes, Adrienne Rich, Nikki Giovanni"
>>> [x.split()[0] for x in authors.split(',')]
['Audre', 'Gabriela', 'Jean', 'An', 'Walt', 'Shel', 'Carmen', 'Kamala', 'Langston', 'Adrienne', 'Nikki']
>>> [x.split()[-1] for x in authors.split(',')]
['Lorde', 'Mistral', 'Toomer', 'Qi', 'Whitman', 'Silverstein', 'Boullosa', 'Suraiyya', 'Hughes', 'Rich', 'Giovanni']
>>> [(x.split()[-1], x.split()[0]) for x in authors.split(',')]
[('Lorde', 'Audre'), ('Mistral', 'Gabriela'), ('Toomer', 'Jean'), ('Qi', 'An'), ('Whitman', 'Walt'), ('Silverstein', 'Shel'), ('Boullosa', 'Carmen'), ('Suraiyya', 'Kamala'), ('Hughes', 'Langston'), ('Rich', 'Adrienne'), ('Giovanni', 'Nikki')]
>>> {(x.split()[-1], x.split()[0]) for x in authors.split(',')}
{('Whitman', 'Walt'), ('Lorde', 'Audre'), ('Suraiyya', 'Kamala'), ('Boullosa', 'Carmen'), ('Toomer', 'Jean'), ('Qi', 'An'), ('Giovanni', 'Nikki'), ('Silverstein', 'Shel'), ('Rich', 'Adrienne'), ('Hughes', 'Langston'), ('Mistral', 'Gabriela')}
>>> {x.split()[-1]: x.split()[0] for x in authors.split(',')}
{'Lorde': 'Audre', 'Mistral': 'Gabriela', 'Toomer': 'Jean', 'Qi': 'An', 'Whitman': 'Walt', 'Silverstein': 'Shel', 'Boullosa': 'Carmen', 'Suraiyya': 'Kamala', 'Hughes': 'Langston', 'Rich': 'Adrienne', 'Giovanni': 'Nikki'}
>>> 

List, Set, Dictionary. Happy trails drawing all three of these together. They make up the entire strategy of data management.

You’re right we don’t really need to index it. Personally, I just like to index it whenever I loop through elements. I like to work with enhanced for loops but either way, I just wanted to make it a one-line approach and it worked!

1 Like

Just to share in my solution here, in case it helps any others as it stumped me for a little while too;

author_count = range(0,len(author_names))
author_last_names = []

for count in author_count:
  name = author_names[count]
  name_split = name.split()
  author_last_names.append(name_split[-1])

My goal was to try and write something that could be easily interpreted, and also theoretically expandable/could work with any size list, and would also work for names that were more than just two parts.

Thank you for this. Really good explanation.

read this thread after writing this code

authors = "Audre Lorde,Gabriela Mistral,Jean Toomer,An Qi,Walt Whitman,Shel Silverstein,Carmen Boullosa,Kamala Suraiyya,Langston Hughes,Adrienne Rich,Nikki Giovanni"
author_names = authors.split(",")
author_last = []
author_last_names = []
for i in author_names:
  author_last.append(i.split())
for i in author_last:
  author_last_names.append(i[1])
print(author_last_names)

I have solved this a bit differently… hope it helps…

authors = “Audre Lorde,Gabriela Mistral,Jean Toomer,An Qi,Walt Whitman,Shel Silverstein,Carmen Boullosa,Kamala Suraiyya,Langston Hughes,Adrienne Rich,Nikki Giovanni”

author_names = authors.split(“,”)
print(author_names)

author_last_names =

for first in author_names:
first_name = first.split()
author_last_names.append(first_name[1])

print(author_last_names)

Output:
[‘Audre Lorde’, ‘Gabriela Mistral’, ‘Jean Toomer’, ‘An Qi’, ‘Walt Whitman’, ‘Shel Silverstein’, ‘Carmen Boullosa’, ‘Kamala Suraiyya’, ‘Langston Hughes’, ‘Adrienne Rich’, ‘Nikki Giovanni’]

[‘Lorde’, ‘Mistral’, ‘Toomer’, ‘Qi’, ‘Whitman’, ‘Silverstein’, ‘Boullosa’, ‘Suraiyya’, ‘Hughes’, ‘Rich’, ‘Giovanni’]

Would you guys hire me if I did the problem like this? :woozy_face:

author_last_names = []
for i in author_names:
  spa = False
  for j in range(len(i)):
    if i[j-1] == " ":
      spa = True
    if spa == True:
      author_last_names.append(i[j:])
      break

print(author_last_names)

i have read your code, it seems to me everything you did is the samei except the split part is written seperately. I was looking for a way to do it, but the suggested way above seems to be the best

Hi,

Thanks for stopping by and your comment. There are numerous ways to write the code and there is no single correct way.

I did complete the video series by David Malan, who is obsessed with simplifying the code. It is kind of nice to learn his ways because it helps to write code in few lines.

Not sure if you were asking how to select only last names??

The split function separates the name into first and last names, although it doesn’t assign it as such. However, both names are stored as index 0, 1. In the code I had written (author_last_names.append(first_name[1])), I picked up 1 - last names. So, if you write the index 0 then the code picks up first names.

Thanks a lot guys for all these explanation !

I had fun with this but also felt somewhat underprepared. There is quite a step-up on difficulty here compared to some of the last chapters as the concepts were explained in more detail before. I used slicing to solve it:

authors_space = authors.replace(“,”, " ")

#print(authors_space)

authors_space_list = authors_space.split()

#print(authors_space_list)

author_last_names = authors_space_list[1::2]

print(author_last_names)

3 Likes

This was so helpful, thank you!

Thank you. Found it very helpful

this is the same code that I put in, but its giving me an error of “list” object has no attribute ‘split’