列表的Python拆分

列表的Python拆分,python,list,Python,List,如果我们在python中有一个列表的字符串,并且想要基于一些特殊的字符串创建子列表,我们应该怎么做 例如: l = ["data","more data","","data 2","more data 2","danger","","date3","lll"] p = split_special(l,"") 将产生: p = [["data","more data"],["data 2","more data 2","danger"],["date3","lll"]] 我不确定这是否是解决这

如果我们在python中有一个
列表
字符串
,并且想要基于一些特殊的
字符串
创建子列表,我们应该怎么做

例如:

l = ["data","more data","","data 2","more data 2","danger","","date3","lll"]
p = split_special(l,"")
将产生:

p = [["data","more data"],["data 2","more data 2","danger"],["date3","lll"]]

我不确定这是否是解决这个问题的最“通灵”的方法

def split_seq(seq, sep):
    start = 0
    while start < len(seq):
        try:
           stop = start + seq[start:].index(sep)
           yield seq[start:stop]
           start = stop + 1
        except ValueError:
           yield seq[start:]
           break

ll = ["data","more data","","data 2","more data 2","danger","","date3","lll"]
p = [i for i in split_seq(ll,"")]
def拆分(seq,sep):
开始=0
启动时
是一种方法(通常是这样):


使用itertools的一种可能实现

>>> l
['data', 'more data', '', 'data 2', 'more data 2', 'danger', '', 'date3', 'lll']
>>> it_l = iter(l)
>>> from itertools import takewhile, dropwhile
>>> [[e] + list(takewhile(lambda e: e != "", it_l)) for e in it_l if e != ""]
[['data', 'more data'], ['data 2', 'more data 2', 'danger'], ['date3', 'lll']]

注*

这和使用groupby一样快

>>> stmt_dsm = """
[list(group) for k, group in groupby(l, lambda x: x == "") if not k]
"""
>>> stmt_ab = """
it_l = iter(l)
[[e] + list(takewhile(lambda e: e != "", it_l)) for e in it_l if e != ""]
"""
>>> t_ab = timeit.Timer(stmt = stmt_ab, setup = "from __main__ import l, dropwhile, takewhile")
>>> t_dsm = timeit.Timer(stmt = stmt_dsm, setup = "from __main__ import l, groupby")
>>> t_ab.timeit(100000)
1.6863486541265047
>>> t_dsm.timeit(100000)
1.5298066765462863
>>> t_ab.timeit(100000)
1.735611326163962
>>> 
我想起:

def split(iterable, where):
    def splitter(acc, item, where=where):
        if item == where:
            acc.append([])
        else:
            acc[-1].append(item)
        return acc
    return reduce(splitter, iterable, [[]])


data = ["data","more data","","data 2","more data 2","danger","","date3","lll"]
print split(data, '')
结果:

[['data', 'more data'], ['data 2', 'more data 2', 'danger'], ['date3', 'lll']]
这里有一个想法


为什么是函数式编程标签?要使用python的函数式编程方法获得答案,您为什么要包括纯粹的示例
groupby(l,lambda x:x=“”)
行?它什么也不做。此外,
[list(group)for k,group in groupby(l,bool),如果k]
应该快10%+以上。@DSM:我错误地添加了它,但删除它并没有太大的距离。顺便说一句,正如你所提到的,同样地,
[list(takewhile(bool,it_l))对于e,如果e!=“e”
也应该同样快,但我仍然觉得,差别可以忽略不计,也可以比较。需要注意的是,python中的
reduce
实际上是CS术语中的
foldl
——CS
reduce
必须用于不关心输入顺序的函数。如果你试图用其他语言
减少
,这可能会给你带来麻烦。+1:这可能是最快的。顺便说一句,您可以使用简单的do
list(split_seq(ll,”)
nice cheat!对于lambda,它可以改进为
lambda x:not x
或只是
操作符。not
def split(iterable, where):
    def splitter(acc, item, where=where):
        if item == where:
            acc.append([])
        else:
            acc[-1].append(item)
        return acc
    return reduce(splitter, iterable, [[]])


data = ["data","more data","","data 2","more data 2","danger","","date3","lll"]
print split(data, '')
[['data', 'more data'], ['data 2', 'more data 2', 'danger'], ['date3', 'lll']]
def spec_split(seq,sep):
    # Ideally this separator will never be in your list
    odd_sep = "!@#$%^&*()"

    # Join all the items with the odd separator and split
    # anywhere the odd separator + separator + odd seperator meet
    # This makes a list of items broken by the separator
    jumble = odd_sep.join(seq).split(odd_sep+sep+odd_sep)

    # split the remaining items broken by odd separators into sublists
    return [item.split(odd_sep) for item in jumble] 
    lst = ["data","more data","","data 2","more data 2","danger","","date3","lll"]
    join_list = ",".join(lst)
    split_list = join_list.split(",,")
    result = [i.split() for i in split_list]
    #result =[['data,more', 'data'], ['data', '2,more', 'data', '2,danger'],  ['date3,lll']]