Pythonic通过条件给定的分隔符

时间:2017-10-08 12:36:32

标签: python functional-programming

我有一个列表,我想把它分成几部分,例如str.split()适用于字符串,但有以下区别:

  1. 分隔符由谓词给出。如果谓词是列表元素的True,则此元素将被视为分隔符。
  2. 我想将结果列在结果列表中。
  3. 例如:

    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。给出了类似的方法here(使用生成器)。

    我尝试找出某种基于itertools的解决方案,例如this one,但如果重复分隔符(例如我的例子中),它们就无法正常工作。

    有没有想法如何以比我现在的代码更多的功能风格来做?

2 个答案:

答案 0 :(得分:5)

您可以将功能简化为:

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

答案 1 :(得分:1)

这个怎么样:

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']]