2017-07-19 93 views
3

我有一个这样的名单:Python的切割清单某个字词

[["tab1", None], ["val1", 10], ["val2", "test"], ["val3", 20], ["tab2", None], ["val4", "test"], ["val5", 30]] 

和我正在寻找那截在正表,如果单词“选项卡”找到一个方法,其结果可能是这个:

list1 = [["val1", 10], ["val2", "test"], ["val3", 20]] 

list2 = [["val4", "test"], ["val5", 30]] 

我尝试了一些循环,但没有做任何事情。

但我不知道这是如何与python可能的。 有人有想法吗?

在此先感谢

+0

列表中是否总是只有两个“tab”? – moritzg

回答

7

我赞成一个简单的for循环此:

In [56]: new_l = [] 

In [57]: for i in l: 
    ...:  if 'tab' in i[0]: 
    ...:   new_l.append([]) 
    ...:  else: 
    ...:   new_l[-1].append(i) 
    ...:   

In [58]: new_l 
Out[58]: 
[[['val1', 10], ['val2', 'test'], ['val3', 20]], 
[['val4', 'test'], ['val5', 30]]] 

有可能是一个更短的解决方案,但我怀疑这会是一个更好的。

编辑:找到一个较短的版本itertools.groupby(还是喜欢循环虽然):

In [66]: [list(v) for _, v in filter(lambda x: x[0], itertools.groupby(l, key=lambda x: 'tab' not in x[0]))]  
Out[66]: 
[[['val1', 10], ['val2', 'test'], ['val3', 20]], 
[['val4', 'test'], ['val5', 30]]] 
+0

希望知道为什么downvote。希望有机会解决任何错误 –

+0

我没有downvoted,但也许你应该改变'if'并包含'any',只是为了安全,如果'tab'在另一个索引中。 – RompePC

+0

@RompePC我不这么认为,看起来标签总是在索引0(如果OP澄清将会改变)。 –

5

下面是使用itertools.groupby()一个Python的方式:即不

In [10]: from itertools import groupby 

In [12]: delimiters = {'tab1', 'tab2'} 

In [13]: [list(g) for k, g in groupby(lst, delimiters.intersection) if not k] 
Out[13]: 
[[['val1', 10], ['val2', 'test'], ['val3', 20]], 
[['val4', 'test'], ['val5', 30]]] 

一个更通用的方法要求指定分隔符,使用lambda函数作为groupby的关键函数(但性能较低):

In [14]: [list(g) for k, g in groupby(lst, lambda x: x[0].startswith('tab')) if not k] 
Out[14]: 
[[['val1', 10], ['val2', 'test'], ['val3', 20]], 
[['val4', 'test'], ['val5', 30]]] 
+1

华丽。当你打败我的时候,我刚开始摆弄itertools来寻找pythonic。 –

+0

不错。不想给你错误的想法,所以只是让你知道我发现我的groupby解决方案独立于你:)(你的更好但是) –

+0

@cᴏʟᴅsᴘᴇᴇᴅ没问题;) – Kasramvd