简体   繁体   English

递归函数在python中拆分列表

[英]Recursive function to split a list in python

I have a function I've written to take a list of arbitrary values and to split it at certain values into sublists. 我编写了一个函数,以获取任意值的列表并将其按特定值拆分为子列表。 Basically, I want to take a list and split it at all occurrences of a specific value, returning a list of sublists. 基本上,我想获取一个列表并在所有出现特定值时将其拆分,以返回子列表的列表。 I figured the easiest way to do this would be via a recursive function as below. 我认为最简单的方法是通过如下的递归函数。

def recsplit(L, val):
    if L.count(val)==0: # If there are no occurrences, return the whole list
        return L
    elif L.index(val)==0: # If the value is the first element, return everything else
        return recsplit(L[1:],val)
    else: # Otherwise, split at the first instance of value
        return L[:L.index(val)], recsplit(L[L.index(val)+1:],val)

The function should work like this: 该功能如下所示:

>>> P = [1,2,3,4,5,None,None,6,7,8,None,9,10,11,None]
>>> recsplit(P,None) 
[[1,2,3,4,5],[6,7,8],[9,10,11]]

Unfortunately I get the following output: 不幸的是,我得到以下输出:

([1, 2, 3, 4, 5, 6, 7], ([8, 9, 10, 11], ([12, 13, 14, 15], [])))

I'm sure there's a way to handle this, but I have tried as many combinations I can think of and none seem to work for me. 我敢肯定有办法解决这个问题,但是我尝试了尽可能多的组合,但似乎没有一种适合我。

I don't think recursion is the easiest way to do this, when you can use itertools.groupby : 我不认为当您可以使用itertools.groupby时,递归是最简单的方法:

from itertools import groupby

lst = [list(g) for k, g in groupby(P, lambda x: x is not None) if k]
print(lst)
# [[1, 2, 3, 4, 5], [6, 7, 8], [9, 10, 11]]

Also keep in mind that recursion is not cheap . 另外请记住,递归并不便宜

As someone already pointed out, recursive function might not be the best way (at least in python) for this specific task. 正如某人已经指出的那样,递归函数可能不是此特定任务的最佳方法(至少在python中)。 But since you asked, here is the code with recursive call to generate the exact output you expected. 但是,正如您所问的那样,这是带有递归调用的代码,用于生成您期望的确切输出。

def recsplit(L, val, out=[[]]):
    if L == []:
        return out
    elif L[0] == val and out[-1] != [] and L[1:].count(val) != len(L[1:]):
        return recsplit(L[1:], val, out + [[]])
    elif L[0] != val and L[0] is not None:
        return recsplit(L[1:], val, out[:-1] + [out[-1] + [L[0]]])
    else:
        return recsplit(L[1:], val, out)

P = [1,2,3,4,5,None,None,6,7,8,None,9,10,11,None]
P1 = [1,2,None,3,4,5,None,"x","x",None,6,7,8,"x",9,10,11,None,"x","x"]  
print("Subs of P by None =", recsplit(P,None))
print("Subs of P1 by x =", recsplit(P1,"x"))
print("Subs of P1 by None =", recsplit(P1,None))

==> ==>

Subs of P by None = [[1, 2, 3, 4, 5], [6, 7, 8], [9, 10, 11]]
Subs of P1 by x = [[1, 2, 3, 4, 5], [6, 7, 8], [9, 10, 11]]
Subs of P1 by None = [[1, 2], [3, 4, 5], ['x', 'x'], [6, 7, 8, 'x', 9, 10, 11], ['x', 'x']]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM