【问题标题】:Split list into lists based on a character occurring inside of an element根据元素内部出现的字符将列表拆分为列表
【发布时间】:2017-12-30 01:47:52
【问题描述】:

在如下列表中:

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]

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

【问题讨论】:

    标签: python list delimiter


    【解决方案1】:

    首先,一个快速的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]
    

    【讨论】:

      【解决方案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', '']]
      

      【讨论】:

      • 这也是一个很好的解决方案,我试过了,效果很好。对于您编辑的部分,它确实为start 提出了NameError
      【解决方案3】:

      这是我没有找到答案的类似问题的解决方案。如何将列表拆分为由成员分隔的子列表,例如人物:

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

      【讨论】:

        【解决方案4】:

        您不需要正则表达式或任何类似的东西 - 一个简单的循环和 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']]
        

        【讨论】:

          猜你喜欢
          • 2018-10-24
          • 2021-11-30
          • 1970-01-01
          • 2021-08-10
          • 2021-08-20
          • 1970-01-01
          • 1970-01-01
          • 2017-04-19
          • 1970-01-01
          相关资源
          最近更新 更多