我有一个列表,我试图通过改变值来分组:
input_list = ["I", "Non-I", "Non-I", "Non-I", "I", "Non-I", "Non-I", "Non-I"]
我需要的是一个输出列表,用于分隔以“I”开头的每个组:
output_list = [["I", "Non-I", "Non-I", "Non-I"], ["I", "Non-I", "Non-I", "Non-I"]]
我尝试过以下方法:
#!/usr/bin/env python3
from itertools import groupby
input_list = ["I", "Non-I", "Non-I", "Non-I", "I", "Non-I", "Non-I", "Non-I"]
output_list = [["I", "Non-I", "Non-I", "Non-I"], ["I", "Non-I", "Non-I", "Non-I"]]
for key, val in groupby(input_list, lambda x: x == "I"):
print(list(val))
......它几乎返回我想要的东西:
['I']
['Non-I', 'Non-I', 'Non-I']
['I']
['Non-I', 'Non-I', 'Non-I']
现在我可以继续合并,即合并所有其他元素,但这似乎是一个黑客。我还提出了迭代的“经典”方式:
ret = []
curr_list = []
for element in input_list:
if element != "I":
curr_list.append(element)
if element == "I":
if curr_list:
ret.append(curr_list)
curr_list = [element]
ret.append(curr_list)
是否有更多的Pythonic方式来实现我的需求?
您可以使groupby
的输出成为生成器表达式,并通过将其自身压缩来配对输出:
from itertools import groupby
groups = (list(g) for _, g in groupby(input_list, 'I'.__eq__))
print([[i for l in pair for i in l] for pair in zip(groups, groups)])
这输出:
[['I', 'Non-I', 'Non-I', 'Non-I'], ['I', 'Non-I', 'Non-I', 'Non-I']]
一种方法是找到一个字符串以"I"
开头的索引,并使用itertools.islice
使用这些索引对列表进行切片:
from itertools import islice
ix = [ix for ix,i in enumerate(input_list) if i[0]=='I'] + [len(input_list)]
input_ = iter(input_list)
[list(islice(input_, i)) for i in ix[1:]]
产量
[['I', 'Non-I', 'Non-I', 'Non-I'], ['I', 'Non-I', 'Non-I', 'Non-I']]
您可以使用索引来存储I
的第一个实例,其中包含以下非I
值:
import itertools
input_list = ["I", "Non-I", "Non-I", "Non-I", "I", "Non-I", "Non-I", "Non-I"]
d = [list(b) for _, b in itertools.groupby(input_list, key=lambda x:x == 'I')]
final_result = [[*d[i], *d[i+1]] for i in range(0, len(d), 2)]
输出:
[['I', 'Non-I', 'Non-I', 'Non-I'], ['I', 'Non-I', 'Non-I', 'Non-I']]
还要查找“I”的索引:s,然后通过切片input_list为每个块创建一个单独的列表。
location_list = [i for i, x in enumerate(input_list) if x == "I"]
[input_list[i:j] for i,j in zip(location_list, location_list[1:]+[len(input_list)])]
随着输出:
[['I', 'Non-I', 'Non-I', 'Non-I'], ['I', 'Non-I', 'Non-I', 'Non-I']]
如果您无法使用itertools,则尝试不使用任何导入。