potentialwjy
potentialwjy

Reputation: 163

return a reformatted string in Python

I have an input string

"First Last, David Joyner, and George Burdell"

I expect an output as formatted string:

Last, F., Joyner, D., & Burdell, G.

To be more specific:

my code

def names_to_apa(mystring):

    result = str()
    my_list = mystring.split(", ") #['First Last', 'David Joyner', 'and George Burdell']

    my_list = [s.strip('and ') for s in my_list] #remove "and ", ['First Last', 'David Joyner', 'George Burdell']
    my_list = [words for segments in my_list for words in segments.split()] #['First', 'Last', 'David', 'Joyner', 'George', 'Burdell']
    for i in range(len(my_list)):
        if i % 2 ==0 and i != (len(my_list)-2): #exclude 4, include 0, 2
            even = str(my_list[i][0] + "., ") #F.,
        elif i == (len(my_list)-1):  #5  --> 'Burdell'
            odd = "& " + str(my_list[i]) + "," #& Burdell
        elif i == (len(my_list)-2):  #4  --> 'George'
            even = str(my_list[i][0] + ".")   #G.
        else:
            odd = str(my_list[i])  #Last,  1,3
            result += odd + ", " + even
    return result

Expected:

Last, F., Joyner, D., & Burdell, G.

Actual:

Last, F., Joyner, D.,

the elif conditions seem incorrect, therefore, & Burdell, G. is missed in the output

Upvotes: 0

Views: 369

Answers (2)

Jongware
Jongware

Reputation: 22457

You don't need to use the even-and-odd toggling. After replacing the , and with a single comma, a split(', ') will return a nice list of all "First Last" pairs. Then you only need to switch these around.

Taking one step at a time – you can insert a print(names) just about anywhere to get an idea what each step does:

def names_to_apa(names):
    names = names.replace(', and ', ', ')
    names = names.split(', ')
    names = [name.split() for name in names]
    names = [name[-1]+', '+(''.join(initial[0]+'.' for initial in name[:-1])) for name in names]
    names = ', '.join(names[:-1])+', & '+names[-1]
    return names

print (names_to_apa("First Last, M. Night Shamalyam, David Joyner, and George Burdell"))

Result:

Last, F., Shamalyam, M.N., Joyner, D., & Burdell, G.

The inner loop comprehension (''.join(initial[0]+'.' for initial in name[:-1]) processes everything before the last name so you can have multiple initials. This will fail (of course) if you have double surnames instead. These need some form of preprocessing.

Upvotes: 0

Rarblack
Rarblack

Reputation: 4664

I have used list-comprehension and simple python string split method:

m = "First Last, David Joyner, and George Burdell"

m_splitted = [i.split() for i in m.strip().split(', ') ]
m_formatted =['& '+value[2]+', '+value[2][0]+'.' if index == len(m_splitted)-1 else value[1]+', '+value[0][0]+'.' for index, value in enumerate(m_splitted)]
m_joined = ', '.join(m_formatted)
print(m_joined)

Output:

C:\Users\Documents>py test.py
Last, F., Joyner, D.,  & Burdell, B.

For your method:

def names_to_apa(mystring):
    m_splitted = [i.split() for i in mystring.strip().split(', ') ]
    m_formatted =[value[2]+', '+value[2][0]+'.' if index == len(m_splitted)-1 else value[1]+', '+value[0][0]+'.' for index, value in enumerate(m_splitted)]
    m_joined = ', '.join(m_formatted)
    return m_joined

Upvotes: 1

Related Questions