根据元素内部出现的字符将列表拆分为列表

时间:2017-07-24 12:53:20

标签: python list delimiter

在如下列表中列出:

biglist = ['X', '1498393178', '1|Y', '15496686585007',
           '-82', '-80', '-80', '3', '3', '2', '|Y', '145292534176372',
           '-87', '-85', '-85', '3', '3', '2', '|Y', '11098646289856',
           '-91', '-88', '-89', '3', '3', '2', '|Y', '35521515162112',
           '-82', '-74', '-79', '3', '3', '2', '|Z',
           '0.0', '0.0', '0', '0', '0', '0', '0', '4', '0', '154']

可能有一些数字元素前面有一个字符。我想把它分成如下的子列表:

smallerlist = [
 ['X', '1498393', '1'],
 ['Y', '1549668', '-82', '-80', '-80', '3', '3', '2', ''],
 ['Y', '1452925', '-87', '-85', '-85', '3', '3', '2', ''],
 ['Y', '3552151', '-82', '-74', '-79', '3', '3', '2', ''],
 ['Z', '0.0', '0.0', '0', '0', '0', '0', '0', '4', '0', '154']
]

正如您所知,根据角色,列表可能看起来很相似。否则,它们可能具有不同数量的元素或完全不同的元素。主分隔符是"|"字符。我试图运行以下代码来拆分列表,但我得到的只是列表中相同的,更大的列表。即,len(list) == 1的列表。

import itertools

delim = '|'
smallerlist = [list(y) for x, y in itertools.groupby(biglist, lambda z: z == delim)
                if not x]

有关如何成功拆分的任何想法?

4 个答案:

答案 0 :(得分:7)

首先,快速 oneliner ,这不是空间要求方面的最佳解决方案,但它简短而且甜美:

,

在这里,我们通过一个独特的非显示分隔符加入大列表的所有元素,例如|,然后按breakby()拆分,然后再将每个列表拆分为原始元素的子列表

但是,如果您正在寻找更多高效解决方案,则可以使用itertools.groupby进行操作,该{{3}}将在中间列表上运行,并使用{{ 1}}生成器,其中没有|分隔符的元素按原样返回,而具有分隔符的元素被分成3个元素:第一部分,列表分隔符(例如None),第二部分

from itertools import groupby

def breakby(biglist, sep, delim=None):
    for item in biglist:
        p = item.split(sep)
        yield p[0]
        if len(p) > 1:
            yield delim
            yield p[1]

smallerlist = [list(g) for k,g in groupby(breakby(biglist, '|', None),
                                          lambda x: x is not None) if k]

答案 1 :(得分:2)

将列表的元素连接到单个字符串会更容易,将字符串拆分为'|'字符,然后将这些元素中的每个元素拆分为用于加入列表的内容。可能是逗号,

bigstr = ','.join(biglist)

[line.split(',') for line in bigstr.split('|')]

# returns
[['X', '1498393178', '1'],
 ['Y', '15496686585007', '-82', '-80', '-80', '3', '3', '2', ''],
 ['Y', '145292534176372', '-87', '-85', '-85', '3', '3', '2', ''],
 ['Y', '11098646289856', '-91', '-88', '-89', '3', '3', '2', ''],
 ['Y', '35521515162112', '-82', '-74', '-79', '3', '3', '2', ''],
 ['Z', '0.0', '0.0', '0', '0', '0', '0', '0', '4', '0', '154']]

如果列表很长,您还可以迭代列表中的项目,在遇到管道符|时创建新的子列表

new_biglist = []
sub_list = []
for item in biglist:
    if '|' in item:
        end, start = item.split('|')
        sub_list.append(end)
        new_biglist.append(sub_list)
        sub_list = [start]
    else:
        sub_list.append(item)

new_biglist
# return:
[['X', '1498393178', '1'],
 ['Y', '15496686585007', '-82', '-80', '-80', '3', '3', '2', ''],
 ['Y', '145292534176372', '-87', '-85', '-85', '3', '3', '2', ''],
 ['Y', '11098646289856', '-91', '-88', '-89', '3', '3', '2', ''],
 ['Y', '35521515162112', '-82', '-74', '-79', '3', '3', '2', '']]

答案 2 :(得分:0)

你不需要正则表达式或任何类似的东西 - 一个简单的循环和str.split()应该绰绰有余,至少如果你是在一个实际有效的解决方案之后:

biglist = ['X', '1498393178', '1|Y', '15496686585007', '-82', '-80', '-80', '3', '3', '2',
           '|Y', '145292534176372', '-87', '-85', '-85', '3', '3', '2', '|Y',
           '11098646289856', '-91', '-88', '-89', '3', '3', '2', '|Y', '35521515162112',
           '-82', '-74', '-79', '3', '3', '2', '|Z', '0.0', '0.0', '0', '0', '0', '0',
           '0', '4', '0', '154']

delimiter = "|"
smaller_list = [[]]
for x in biglist:
    if delimiter in x:
        a, b = x.split(delimiter)
        if a:  # remove the check if you also want the empty elements
            smaller_list[-1].append(a)
        smaller_list.append([])
        if b:  # remove the check if you also want the empty elements
            smaller_list[-1].append(b)
    else:
        smaller_list[-1].append(x)

print(smaller_list)
# [['X', '1498393178', '1'],
#  ['Y', '15496686585007', '-82', '-80', '-80', '3', '3', '2'],
#  ['Y', '145292534176372', '-87', '-85', '-85', '3', '3', '2'],
#  ['Y', '11098646289856', '-91', '-88', '-89', '3', '3', '2'],
#  ['Y', '35521515162112', '-82', '-74', '-79', '3', '3', '2'],
#  ['Z', '0.0', '0.0', '0', '0', '0', '0', '0', '4', '0', '154']]

答案 3 :(得分:0)

这是我找不到答案的类似问题的解决方案。如何将列表分成由成员分隔的子列表,例如字符:

l = ['r', 'g', 'b', ':',
     'D', 'E', 'A', 'D', '/',
     'B', 'E', 'E', 'F', '/',
     'C', 'A', 'F', 'E']

def split_list(thelist, delimiters):
    ''' Split a list into sub lists, depending on a delimiter.

        delimiters - item or tuple of item
    '''
    results = []
    sublist = []

    for item in thelist:
        if item in delimiters:
            results.append(sublist) # old one
            sublist = []            # new one
        else:
            sublist.append(item)

    if sublist:  # last bit
        results.append(sublist)

    return results


print(
    split_list(l, (':', '/'))
)
# => [['r', 'g', 'b'], ['D', 'E', 'A', 'D'], 
#     ['B', 'E', 'E', 'F'], 
#     ['C', 'A', 'F', 'E']]