【问题标题】:Python: split list of integers based on step between themPython:根据整数之间的步长拆分整数列表
【发布时间】:2013-02-07 19:37:22
【问题描述】:

我有以下问题。有一个整数列表,我想将它拆分为一个列表列表,只要原始输入列表的两个元素之间的步长不是 1。 例如:输入 = [0, 1, 3, 5, 6, 7],输出 = [[0, 1], [3], [5, 6, 7]]

我编写了以下函数,但它非常丑陋,我想知道你们中的任何人是否会帮助我获得更好的解决方案。我尝试使用itertools,但无法解决。

这是我的解决方案:

def _get_parts(list_of_indices):
    lv = list_of_indices
    tuples = zip(lv[:-1], lv[1:])
    split_values = []
    for i in tuples:
        if i[1] - i[0] != 1:
            split_values.append(i[1])
    string = '/'.join([str(i) for i in lv])
    substrings = []
    for i in split_values:
        part = string.split(str(i))
        substrings.append(part[0])
        string = string.lstrip(part[0])
    substrings.append(string)
    result = []
    for i in substrings:
        i = i.rstrip('/')
        result.append([int(n) for n in i.split('/')])
    return result

非常感谢!

【问题讨论】:

    标签: python list split integer indices


    【解决方案1】:

    这适用于任何可迭代对象

    >>> from itertools import groupby, count
    >>> inp = [0, 1, 3, 5, 6, 7]
    >>> [list(g) for k, g in groupby(inp, key=lambda i,j=count(): i-next(j))]
    [[0, 1], [3], [5, 6, 7]]
    

    【讨论】:

    • 不错的解决方案。我认为描述会很有用:j=count() 创建一个计数器。对next(j) 的每次调用都会以 1 为单位返回 int。不明显的 python 行为:函数参数的默认值在函数创建时创建一次。因此,j 将仅使用 count() 初始化一次,在下次调用 key 时,arg j 将具有先前创建的实例。 groupby 将附加到可迭代的 g 来自 inp 的所有具有相同键值的项目。如果键值已更改 - 创建新的 g。对于来自 inp 的项目:item=0,key=0-0=0;项目=1,键=1-1=0;项目=3,键=3-2=1; item=5,key=5-3=2 等等。
    【解决方案2】:
    def _get_parts(i, step=1):
        o = []
        for x in i:
            if o and o[-1] and x - step == o[-1][-1]:
                o[-1].append(x)
            else:
                o.append([x])
        return o
    
    _get_parts([0, 1, 3, 5, 6, 7], step=1)
    # [[0, 1], [3], [5, 6, 7]])
    

    【讨论】:

      【解决方案3】:

      这是一个利用 for 循环的解决方案。

      def splitbystep(alist):
        newlist = [[alist[0]]]
        for i in range(1,len(alist)):
          if alist[i] - alist[i-1] == 1:
            newlist[-1].append(alist[i])
          else:
            newlist.append([alist[i]])
        return newlist
      

      【讨论】:

        【解决方案4】:

        这就是我的做法:

        inp = [0, 1, 3, 5, 6, 7]
        base = []
        
        for item in inp:
            if not base or item - base[-1][-1] != 1: # If base is empty (first item) or diff isn't 1
                base.append([item])                  # Append a new list containing just one item
            else:
                base[-1].append(item)                # Otherwise, add current item to the last stored list in base
        print base                                   # => [[0, 1], [3], [5, 6, 7]]
        

        【讨论】:

          【解决方案5】:

          这是function split_when from module more_itertools 的教科书用例:

          import more_itertools
          
          print(list(more_itertools.split_when([0, 1, 3, 5, 6, 7], lambda x,y: y-x != 1)))
          # [[0, 1], [3], [5, 6, 7]]
          

          或者,使用more_itertools.consecutive_groups 更简单:

          print([list(g) for g in more_itertools.consecutive_groups([0, 1, 3, 5, 6, 7])])
          # [[0, 1], [3], [5, 6, 7]]
          

          【讨论】:

            猜你喜欢
            • 2016-01-08
            • 2021-01-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-03-21
            • 2012-09-05
            相关资源
            最近更新 更多