2012-06-01 4 views
10

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

Пример:

s = 'long string that I want to split up' 
indices = [0,5,12,17] 
parts = [s[index:] for index in indices] 
for part in parts: 
    print part 

Это вернет:

длинная строка, что я хочу, чтобы разделить
строку, которую я хочу разделить
, что я хочу разделить
Я хочу разделить

Я пытаюсь получить:

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

ответ

15
s = 'long string that I want to split up' 
indices = [0,5,12,17] 
parts = [s[i:j] for i,j in zip(indices, indices[1:]+[None])] 

возвращается

['long ', 'string ', 'that ', 'I want to split up'] 

, который можно распечатать с помощью:

print '\n'.join(parts) 

Другой возможности (без копирования indices) будет:

s = 'long string that I want to split up' 
indices = [0,5,12,17] 
indices.append(None) 
parts = [s[indices[i]:indices[i+1]] for i in xrange(len(indices)-1)] 
+1

Другой способ: '[s [i: j] для i, j в izip_longest (индексы, индексы [1:])]', но мне нравится ваш путь лучше! – jamylak

+0

Это копирует список индексов с помощью 'index [1:]' и создает новый список с двойным размером функцией 'zip' -> Плохая производительность и потребление памяти. – schlamar

+2

@ ms4py Это хорошо, производительность не является проблемой в этом случае, это очень читаемое решение. Если производительность является проблемой, мое предложение может быть использовано. – jamylak

3

Вот краткое решение с Интенсивным использованием itertools module. Функция tee используется для итерации попарно по индексам. Дополнительную информацию см. В разделе Рецепт в модуле.

>>> from itertools import tee, izip_longest 
>>> s = 'long string that I want to split up' 
>>> indices = [0,5,12,17] 
>>> start, end = tee(indices) 
>>> end.next() 
0 
>>> [s[i:j] for i,j in izip_longest(start, end)] 
['long ', 'string ', 'that ', 'I want to split up'] 

Edit: Это версия, которая не копирует список индексов, поэтому она должна быть быстрее.

+0

Спасибо за альтернативный подход - не забудьте проверить itertools когда-нибудь – Yarin

+0

Уютный подход, узнал что-то новое. Есть ли простой способ избавиться от лишнего пробела в конце первых трех строк внутри выражения? Я пробовал 's [i: j] .strip()', но это вообще не сработало (не знаю, почему нет) – Levon

+0

Если вы собираетесь использовать это, вы также можете использовать парную функцию прямо из документов itertools. Также использование 'next (end)' предпочтительнее 'end.next()' для совместимости с python 3. – jamylak

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