2012-04-30 2 views
3

У меня есть набор имен, в которых фамилия находится в капитале, а первые и средние имена являются нормальными, например.Разделить строку слов по прописным словам

OBAMA Barack 
DEL MONTE Alfredo 

Я хочу, чтобы разделить их в

"OBAMA", "Barack" 
"DEL MONTE", "Alfredo" 

Что такое вещий способ для достижения этой цели?

+3

Обама - фамилия Барака Обамы. –

+1

Спасибо. Хотя это был пример, я меняю его, чтобы избежать путаницы. – imsc

ответ

8
>>> import itertools 
>>> [ 
... ' '.join(items) 
... for _, items in itertools.groupby('DEL MONTE Alfredo'.split(), str.isupper) 
... ] 
['DEL MONTE', 'Alfredo'] 
+2

+1 это действительно pythonic. – eumiro

+1

Я считаю это элегантным, но я честно сомневаюсь, что это то, что большинство Pythonistas рассмотрит Pythonic. Кажется, я немного по-другому думаю о некоторых вещах :) Моя первая мысль была о «itertools.takewhile», но я остановился на «groupby», когда понял, что «takewhile» не совсем сделал трюк (или, по крайней мере, это нужно повторить и выглядеть очень грязно). –

+0

Я также пробовал его с 'takewhile', но' groupby' - это элегантный способ пойти. – eumiro

2
def split_names(names): 
    for s in names: 
     last_names = [] 
     name_parts = s.split() 
     while name_parts and name_parts[0].isupper(): 
      last_names.append(name_parts.pop(0)) 
     yield ' '.join(last_names), ' '.join(name_parts) 


names = ["OBAMA Barack", "DEL MONTE Alfredo"] 
for last_name, first_name in split_names(names): 
    print last_name 
    print first_name 
    print 

печатает:

OBAMA 
Barack 

DEL MONTE 
Alfredo 
+0

Могу я предложить переименовать 'firstnames' ->' name_parts', 'lastnames' ->' last_names'; и вы хотите протестировать всю строку для '.isupper()', поскольку вы хотите присоединять к последним именам только тогда, когда имя принадлежит всем в верхнем регистре. –

+0

@KarlKnechtel: 'firstnames [0] .isupper()' проверяет все слово (первое в списке) на случай, а затем выдает его и добавляет к 'lastnames'. Переименование в 'name_parts' и' last_names' имеет смысл. – eumiro

+0

О, извините, я неправильно проанализировал это. –

0

Попробуйте это:

(?![A-Z][a-z])([A-Z ]+) ([A-Z][a-z]+) 
+2

Было бы ясно, что это регулярное выражение и как вы собираетесь его использовать. I.e., покажите фактический код кадрирования. –

2

Вы можете использовать простое регулярное выражение:

import re 

a = "DEL MONTE Alfredo" 
first, last = re.match(r'([A-Z ]+)\s+(.+)', a).groups() 

или петля через список слов и отфильтровать все-заглавных:

first = ' '.join(w for w in a.split() if w.isupper()) 
last = ' '.join(w for w in a.split() if not w.isupper()) 

По моему личному мнению, «самый вещий» === «самый простой».

Смежные вопросы