标记lis

2024-04-16 07:57:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我喜欢使用列表项作为分隔符来标记列表。你知道吗

是有一个Python的方式来做这件事,还是我必须写一些我自己。你知道吗

Data=['Label',23,'NORM','|','RESP',1.256,None,'|','','','|','RELV','','']
SubList = TokenizeList (Data,Delim='|')

打印子列表将导致

[ ['Label',23,'NORM'] , ['RESP',1.256,None] , ['',''] , ['RELV','',''] ]

Tags: 标记nonenorm列表data方式resplabel
3条回答

试试这个,简单而直截了当的(同样是Python式的)

def tokenize_list(array, sep='|'):
    result = []
    _temp = []
    for el in array:
        if el == sep:
            result.append(_temp)
            _temp = []
        else:
            _temp.append(el)
    if _temp: # Finally append list after for-loop, to store last vlaues present in _temp if exists.
        result.append(_temp) 
    return result

输出:

>>> data = ['Label',23,'NORM','|','RESP',1.256,None,'|','','','|','RELV','','', '|']
>>> tokenize_list(data)
[['Label', 23, 'NORM'], ['RESP', 1.256, None], ['', ''], ['RELV', '', '']]

是的,您可以使用^{}

>>> from itertools import groupby
>>> Data=['Label',23,'NORM','|','RESP',1.256,None,'|','','','|','RELV','','']
>>> [list(g) for k,g in groupby(Data,key=lambda x:x == '|') if not k]
[['Label', 23, 'NORM'], ['RESP', 1.256, None], ['', ''], ['RELV', '', '']]

当然,你可以做一个函数:

def splitList(sequence, delimiter):
    return [list(g) for k, g in groupby(sequence, key = lambda x: x == delimiter) if not k]
>>> splitList(sequence = Data, delimiter = '|')
[['Label', 23, 'NORM'], ['RESP', 1.256, None], ['', ''], ['RELV', '', '']]

试试这个:

def group_by_sep(items, sep='|'):
    inner_list = []
    for item in items:
        if item == sep:
            yield inner_list
            inner_list = []
        else:
            inner_list.append(item)
    if inner_list:
        yield inner_list


Data=['Label',23,'NORM','|','RESP',1.256,None,'|','','','|','RELV','','','|','|','now','|']

SubList = list(group_by_sep(Data, '|'))
print(SubList)
# [['Label', 23, 'NORM'], ['RESP', 1.256, None], ['', ''], ['RELV', '', ''], [], ['now']]

请注意,这里可以使用itertools.groupby方法,但它不等同于上述方法,并且对确切的行为提供较少的控制:

import itertools


def group_by_sep2(items, sep='|'):
    yield from (
        list(g)
        for k, g in itertools.groupby(items, key=lambda x: x == sep)
        if not k)


SubList2 = list(group_by_sep2(Data, '|'))
print(SubList2)
# [['Label', 23, 'NORM'], ['RESP', 1.256, None], ['', ''], ['RELV', '', ''], ['now']]

它缺少两个连续分隔符之间的空list。你知道吗

此外,它不如上面的直接方法有效:

%timeit list(group_by_sep(Data))
# 1000 loops, best of 3: 1.47 µs per loop
%timeit list(group_by_sep2(Data))
# 100 loops, best of 3: 4.01 µs per loop

%timeit list(group_by_sep(Data * 1000))
# 1000 loops, best of 3: 1.33 ms per loop
%timeit list(group_by_sep2(Data * 1000))
# 100 loops, best of 3: 2.83 ms per loop

%timeit list(group_by_sep(Data * 1000000))
# 1000 loops, best of 3: 1.67 s per loop
%timeit list(group_by_sep2(Data * 1000000))
# 100 loops, best of 3: 3.22 s per loop

基准测试表明,直接法的速度快了2到3倍。你知道吗

(编辑为将其全部作为生成器编写,并包含更多的边缘案例)

相关问题 更多 >