2013-02-18 8 views
2

Представьте себе У меня есть следующий список:создать список подстрок нескольких линий

result_lines = ['name1 age1 address1 email1', 
       'name2 age2 address2 email2', 
       'name3 age3 address3 email3'] 

Я хотел бы, чтобы напечатать следующую строку:

'age1:name1, age2:name2, age3: name3' 

Примечание: не , в конце строки !

ОБНОВЛЕНИЕ: важен не порядок age1:name1. это также может быть age1:email1:name1.

То, что я пытался до сих пор:

print "".join((l.split(' ')[1], l.split(' ')[0]) for l in result_lines) 

Однако, я получаю следующее сообщение об ошибке:

TypeError: sequence item 0: expected string, tuple found 

Спасибо за любую помощь.

+2

Совет: Вам не нужно использовать '' \ '' продолжения обратной косой черты внутри '[..]', '{..}' или '(..)' пар в Python. Синтаксический анализатор знает, что вы еще не сделали, когда он еще не нашел балансировочную закрывающую фигуру на той же линии. –

+0

@MartijnPieters: спасибо! изменил это. – ezdazuzena

ответ

6

str.format() является вашим другом в ситуации, когда вы хотите, чтобы представить содержимое list или tuple:

>>> ', '.join(['{1}:{0}'.format(*line.split()) for line in result_lines]) 
'age1:name1, age2:name2, age3:name3' 

Чтобы сломать это немного, потому что в этой линии много чего происходит ...

Мы начнем с простого списка понимания:

>>> [line for line in result_lines] 
['name1 age1 address1 email1', 'name2 age2 address2 email2', 'name3 age3 address3 email3'] 

И разделить строку на пробелы с помощью str.split() (нам нужно только разделить раз):

>>> [line.split() for line in result_lines] 
[['name1', 'age1', 'address1', 'email1'], ['name2', 'age2', 'address2', 'email2'], ['name3', 'age3', 'address3', 'email3']] 

Представьте str.format() и unpack the argument list:

>>> ['{0}:{1}:{2}:{3}'.format(*line.split()) for line in result_lines] 
['name1:age1:address1:email1', 'name2:age2:address2:email2', 'name3:age3:address3:email3'] 

Выберите элементы, которые мы хотим:

>>> ['{1}:{0}'.format(*line.split()) for line in result_lines] 
['age1:name1', 'age2:name2', 'age3:name3'] 

(str.) join все это вместе с ', ':

>>> ', '.join(['{1}:{0}'.format(*line.split()) for line in result_lines]) 
'age1:name1, age2:name2, age3:name3' 

что и требовалось доказать

+1

Спасибо, это именно то, что я искал. – ezdazuzena

1

Это должно сделать работу:

>>> result_lines = ['name1 age1 address1 email1', \ 
...     'name2 age2 address2 email2', \ 
...     'name3 age3 address3 email3'] 
>>> print ", ".join([l.split(' ')[1] + ': ' + l.split(' ')[0] for l in result_lines]) 
age1: name1, age2: name2, age3: name3 
4

Чтобы сделать это в одной строке без нескольких вызовов расколоть вам нужно отменить и нарезать .split() результат, а гнездо ваша строка присоединяется:

', '.join([':'.join(line.split()[:2][::-1]) for line in result_lines]) 

Таким образом, каждая запись в списке:

  • Split на пробельных
  • Нарезанный, чтобы указать имя и возрастные записи
  • Обратный так, что возраст приходит до имени, используя [::-1], чтобы обратить вспять на место.
  • Зарегистрировался ':', чтобы получить age?:name? пар.
  • Мы используем понимание списка ([ ... for .. in ... ]), потому что это происходит быстрее с str.join(). Внутренне, .join() вычисляет окончательную длину строки перед присоединением и будет лить генератор в список в любом случае. Постижение затем выигрывает на скорости.

Тогда весь список объединен с ', ', чтобы дать хороший список, разделенный запятой. Потому что мы только разделить раз это будет работать

Это дает:

>>> ', '.join([':'.join(line.split()[:2][::-1]) for line in result_lines]) 
'age1:name1, age2:name2, age3:name3' 
+1

+1: Хотя я считаю, что мое решение более читаемо, это отличное объяснение (особенно в отношении 'str.join()' и 'list', чего я не знал). – Johnsyweb

+0

Почему '.join' _need_ для вычисления конечной длины строки? – wim

+0

@wim: он выделяет окончательный размер строки C. Для этого не потребуется перераспределять новую строку для каждого элемента во входном списке минус один. Это очень * неэффективно. –

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