2016-08-17 38 views
1

我想分割字典列表if the value is empty并创建列表的新列表。如果值为空,请拆分字典列表?

输入:

[{'k':'a'},{'k':'b'},{'k':''},{'k':'d'},{'k':''},{'k':'f'},{'k':'g'}] 

输出:

[[{'k': 'a'}, {'k': 'b'}, {'k': ''}], [{'k': 'd'}, {'k': ''}], [{'k': 'f'}, {'k': 'g'}]] 

我一直在使用循环,如果其工作正常审判。

sub_header_list = [{'k':'a'},{'k':'b'},{'k':''},{'k':'d'},{'k':''},{'k':'f'},{'k':'g'}] 
index_data = [] ; data_list = [] 
for i in sub_header_list: 
    index_data.append(i) 
    if i['k'] == '': 
     data_list.append(index_data) 
     index_data = [] 
print(data_list+[index_data]) 

[[{'k': 'a'}, {'k': 'b'}, {'k': ''}], [{'k': 'd'}, {'k': ''}], [{'k': 'f'}, {'k': 'g'}]] 

是否有任何pythonic方式来实现相同的,我的意思是通过使用内置的函数或别的东西?

+0

哪里原始数据从何而来? –

+0

如果没有别的,你应该将你的for循环移入一个函数。 –

+0

原始数据来自数据框,然后我正在创建字典,我已经解决了原始数据,但它没有帮助, –

回答

2

这是做它的另一种Python的方式:

>>> d = [{'k':'a'}, {'k':'b'}, {'k':''}, {'k':'d'}, {'k':''}, {'k':'f'}, {'k':'g'}] 
>>> index_list = [i + 1 for i, x in enumerate(d) if x == {'k': ''}] 
>>> [d[i:j] for i, j in zip([0] + index_list, index_list + [len(d)])] 
[[{'k': 'a'}, {'k': 'b'}, {'k': ''}], [{'k': 'd'}, {'k': ''}], [{'k': 'f'}, {'k': 'g'}]] 
+1

Upvoted你的答案,谢谢:) –

2

您可以使用groupby

from itertools import groupby, chain 


l = [{'k':'a'},{'k':'b'},{'k':''},{'k':'d'},{'k':''},{'k':'f'},{'k':'g'}] 

grps = groupby(l, lambda d: d["k"] == "") 

print([list(chain(*(v, next(grps, [[], []])[1]))) for k, v in grps if k]) 

输出:

[[{'k': 'a'}, {'k': 'b'}, {'k': ''}], [{'k': 'd'}, {'k': ''}], [{'k': 'f'}, {'k': 'g'}]] 

或者使用发电机功能:

def grp(lst,): 
    temp = [] 
    for dct in lst: 
     # would catch None, 0, for just empty strings use if dct["k"] == "". 
     if not dct["k"]: 
      temp.append(dct) 
      yield temp 
      temp = [] 
     else: 
      temp.append(dct) 
    yield temp 

它给你同样的输出:

In [9]: list(grp(l)) 
Out[9]: 
[[{'k': 'a'}, {'k': 'b'}, {'k': ''}], 
[{'k': 'd'}, {'k': ''}], 
[{'k': 'f'}, {'k': 'g'}]] 

发电机功能是迄今为止最有效的方法。

In [8]: l = [{'k':'a'}, {'k':'b'}, {'k':''}, {'k':'d'}, {'k':''}, {'k':'f'}, {'k':'g'}] 

In [9]: l = [dict(choice(l)) for _ in range(100000)] 

In [10]: timeit list(grp(l)) 
10 loops, best of 3: 19.5 ms per loop 

In [11]: %%timeit 
index_list = [i + 1 for i, x in enumerate(l) if x == {'k': ''}] 
[l[i:j] for i, j in zip([0] + index_list, index_list + [len(l)])] 
    ....: 
10 loops, best of 3: 31.6 ms per loop 

In [12]: %%timeit     grps = groupby(l, lambda d: d["k"] == "") 
[list(chain(*(v, next(grps, [[], []])[1]))) for k, v in grps if k] 
    ....: 
10 loops, best of 3: 40 ms per loop 
+1

Upvoted你的答案:)非常感谢,它很难选择你的答案和@Selcuk –

+1

不用担心,不用客气。 –