2013-02-12 3 views
0

Пусть у меня есть строка, например, так:Python itertools не GroupBy группировки, как я ожидал

st='''Line 1 
Line 2 
Line 3 
Line 4 

Line 5 
Line 6 

Line 7 
Line 8 
Line 9 

Line 10 
Line 11 
Line 12 
Line 13 
Line 14''' 
# may be really big... 

Теперь предположим я хочу Лола, сгруппированных по пустым строкам:

[['Line 1', 'Line 2', 'Line 3', 'Line 4'], 
['Line 5', 'Line 6'], 
['Line 7', 'Line 8 ', 'Line 9'], 
['Line 10', 'Line 11', 'Line 12', 'Line 13', 'Line 14']] 

Я знаю, что я могу создать что LoL с регулярными выражениями раскола:

[[x] for x in re.split(r'^\s*\n',st,flags=re.MULTILINE)] 

Однако, я пытаюсь создать это с помощью генератора Python не-регулярных выражений. Ближайший я получил это ужасная вещь (которая включает в себя пробелы и не совсем эффективным, я знаю ...):

result=[]   
for sub in (group for key, group in itertools.groupby(st.splitlines(), lambda x: not x.rstrip())): 
    result.append(list(sub)) 

print result 

Любые намеки на направлении идти?

Я немного брелок THIS SO question.

+0

Кстати, ваш последний цикл может быть упрощено до '[ list (group) для _, group in itertools.groupby (st.splitlines(), lambda x: not x.rstrip())] '. –

ответ

2

Я бы, наверное, написать

>>> grouped = itertools.groupby(map(str.strip, st.splitlines()), bool) 
>>> [list(g) for k,g in grouped if k] 
[['Line 1', 'Line 2', 'Line 3', 'Line 4'], ['Line 5', 'Line 6'], 
['Line 7', 'Line 8', 'Line 9'], ['Line 10', 'Line 11', 'Line 12', 'Line 13', 'Line 14']] 

Это будет также обрабатывать пустые строки с пробелами, которые \n\n основанное расщепление не будет. С другой стороны, он не сохраняет начальные и конечные пробелы, которые из примера 'Line 8 ' вы можете захотеть. Если это имеет значение, вы могли бы сделать:

grouped = itertools.groupby(st.splitlines(), lambda x: bool(x.strip())) 

(который, глядя на него, довольно близко к тому, что вы уже делаете.)

+0

Drak! (headlap) Это SECOND ('[list (g) для k, g в сгруппированном, если k]') понимании, которое я отсутствовал! Благодаря! –

2

Возможно ли, что это не сработает для вас?

>>> lol = [group.split("\n") for group in st.split("\n\n")] 
>>> pprint(lol) 
[['Line 1', 'Line 2', 'Line 3', 'Line 4'], 
['Line 5', 'Line 6'], 
['Line 7', 'Line 8 ', 'Line 9'], 
['Line 10', 'Line 11', 'Line 12', 'Line 13', 'Line 14']] 
+0

Это здорово (+1), но то, на что я надеялся, - это генерал генерала порошков. См. Редактирование вопроса. –