2013-02-12 29 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)for _,group in itertools.groupby(st.splitlines(),lambda x:not x.rstrip())]'。 – 2013-02-12 23:32:14

回答

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

德拉克! (headlap)这是SECOND('[k(g),g(如果k)])理解我失踪了!谢谢! – 2013-02-12 23:40:54

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),但我希望的是一个有点普通的阴户发生器。请参阅编辑问题。 – 2013-02-12 23:28:08