我有一个列表,我想把它分成几部分,就像str.split()
适用于字符串一样,具有以下区别:
- 分隔符由谓词给出。如果对列表的元素
True
谓词,则此元素被视为分量表。 - 我想将分量计保留在结果列表中。
例如:
split_by_predicate([0, "One", 1, 2, 3,
"Two", 4, 5, 6, 7, "Three", "Four"],
predicate=lambda x: isinstance(x, str))
应该给我
[[0], ["One", 1, 2, 3], ["Two", 4, 5, 6, 7], ["Three"], ["Four"]]
我可以编写以下代码:
def split_by_predicate(it, predicate):
lst = []
cur = []
for element in it:
if predicate(element):
lst.append(cur)
cur = []
cur.append(element)
lst.append(cur)
return lst
但我发现它不优雅,也不是Pythonic。这里给出了类似的方法(使用生成器)。
我试图找出某种像这样的基于 itertools
的解决方案,但如果重复分寸仪(如我的示例),它们将无法正常工作。
有什么想法如何以比我当前的代码更实用的风格做到这一点吗?
您可以将函数简化为:
def split_by_predicate(it, predicate):
lst = [[]]
for element in it:
if predicate(element):
lst.append([])
lst[-1].append(element)
return lst
或者这个(在第一次迭代时跳过附加空列表):
def split_by_predicate(it, predicate):
lst = [[]]
for i, element in enumerate(it):
if predicate(element) and i:
lst.append([])
lst[-1].append(element)
return lst
这个呢:
def split_by_predicate(it, predicate):
o = []
for i in it:
if predicate(i) or len(o) == 0:
o += [[i]]
else:
o[-1] += [i]
return o
输出:
>>> split_by_predicate([0, 'One', 1, 2, 3, 'Two', 4, 5, 6, 7, 'Three', 'Four'], lambda x: isinstance(x,str))
[[0], ['One', 1, 2, 3], ['Two', 4, 5, 6, 7], ['Three'], ['Four']]