There is a list of names of people in Russian. Something like this:

full_names = [u"Иванов Иван Иванович", u"Петров Петр Петрович"]

My task is to shorten their full name to "Last Name IO" in the most compact form. I'm trying to do this:

 full_names = [u"Иванов Иван Иванович", u"Петров Петр Петрович"] short_names = [' '.join([fn.split(' ')[0],fn.split(' ')[0][1]]) for fn in full_names] 

This is how you can get the format "Last Name And"

Is there a more elegant way?

  • why one line? - Grundy
  • So the task becomes more interesting. A multi-line solution will look trite :) - Skotinin
  • 2
    If this is a code golf question, then follow the rules for such questions (look at Stack Overflow in Russian Meta ). If not, remove the restriction for one line or explain what caused this requirement. - jfs
  • I do not know what a code golf question is. This is for my personal needs. Well, let it be a lot of lines. - Skotinin

3 answers 3

Better use the standard format:

{: .1} - takes only the first character

 ['{} {:.1}. {:.1}.'.format(*n.split()) for n in full_names] 

name / middle name is no longer necessary:

 def get_full_names(names: list): def fio_name(fio: str): ifs = iter(fio.split()) yield next(ifs) for name in ifs: yield name[0]+'.' return [' '.join(fio_name(n)) for n in names] 
  • Do not forget to test such functions, for example, such full names of Ashurshanova Leyla Sadar Kyzy - 4per

If in one line and if the format is strictly u"Фамилия Имя Отчество" (exactly two spaces), then I did it like this:

 short_names = [u'{} {}. {}.'.format(x[:x.find(' ')], x[x.find(' ') + 1], x[x.rfind(' ') + 1]) for x in full_names] 

Deployed:

 short_names = [ u'{} {}. {}.'.format( # Шаблон, в который подставим строки x[:x.find(' ')], # Всё до первого пробела - Фамилия x[x.find(' ') + 1], # Первая буква после первого пробела - И. x[x.rfind(' ') + 1] # Первая буква после последнего пробела - О. ) for x in full_names ] 

But still, for something serious, I strongly recommend using some kind of clear multiline variant, because it is safer, easier to maintain and easier to expand under unforeseen situations (for example, not all people have a patronymic, and such a one-line breaks down).

  • short_names = [' '.join([fn.split(' ')[0],fn.split(' ')[1][0],fn.split(' ')[2][0]]) for fn in full_names] - Skotinin

One line using the names from the question:

 short_names = map(shorten_to_initials, full_names) 

where the definition of shorten_to_initials() can be moved to another place in the code without losing understanding:

 def shorten_to_initials(full_name): """u'Иванов Иван Петрович' -> u'Иванов И.П.'""" last, name, patronymic = full_name.split() return u"{last} {name[0]}.{patronymic[0]}.".format(**vars()) 

This may break, for example, for letters consisting of several characters. See Falsehoods Programmers Believe About Names .

Do not abuse abbreviations like: "{} {[0]}.{[0]}.".format(*full_name.split()) in Python.