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

新手上路,请多包涵

在如下列表中:

 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]

任何想法如何成功拆分它?

原文由 omrakhur 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 526
2 个回答

首先,一个快速的 oneliner ,就空间要求而言,这不是最佳解决方案,但它又短又好:

 >>> smallerlist = [l.split(',') for l in ','.join(biglist).split('|')]
>>> smallerlist
[['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']]

在这里,我们通过一个唯一的未出现的分隔符连接大列表的所有元素,例如 , ,然后通过 | 拆分,然后再次将每个列表拆分为原始列表的子列表元素。

但是,如果您正在寻找更 有效的解决方案,您可以使用 itertools.groupby 来实现,它将在中间列表上运行,使用 breakby() 生成器即时生成,其中元素没有 | 分隔符按原样返回,那些有分隔符的元素被分成 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]

原文由 randomir 发布,翻译遵循 CC BY-SA 3.0 许可协议

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

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

原文由 James 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题