【问题标题】:How can I split an integer into a list of n length evenly in Python 3.5?如何在 Python 3.5 中将整数平均拆分为长度为 n 的列表?
【发布时间】:2016-08-25 04:43:51
【问题描述】:

我需要能够将一个整数平均拆分为一个长度为 n 的列表。

例如 n = 4,

12 -> [0, 0, 1, 2]
1234 -> [1, 2, 3, 4]
12345 -> [1, 2, 3, 45]
123456 -> [1, 2, 34, 56]
1234567 -> [1, 23, 45, 67]
12345678 -> 12, 34, 56, 78]
123456789 -> [12, 34, 56, 789]

我敢肯定,我给出的例子太多了,但这有助于理解重点。

我过去用来将项目拆分为列表的代码是:

def split(s, chunk_size):
    a = zip(*[s[i::chunk_size] for i in range(chunk_size)])
    return [''.join(t) for t in a]

但是这段代码只分成 n 块。 (来自 StackOverflow 的代码,我不记得确切的帖子了,抱歉)。

感谢您的帮助。

【问题讨论】:

    标签: python python-3.x


    【解决方案1】:
    def split(seq, n):
        """Partitions `seq` into `n` successive slices of roughly equal size.
    
        The sizes of each yielded slice shall differ by at most one.
        """
        q, r = divmod(len(seq), n)
        start = 0
    
        for i in range(n):
            size = q + (i < r)
            yield seq[start : start + size]
            start += size
    

    它的工作方式与this popular answer 基本相同,只是它将剩余部分均匀地分配到每个 n 个切片中。

    不幸的是,这将分配到列表的头部。要根据您的情况对其进行调整,您需要将 size = q + (i &lt; r) 更改为:

    size = q + (i >= (n - r))
    

    通过此更改,以下内容:

    print(list(split('1234', 4)))
    print(list(split('12345', 4)))
    print(list(split('123456', 4)))
    print(list(split('1234567', 4)))
    print(list(split('12345678', 4)))
    print(list(split('123456789', 4)))
    

    打印:

    ['1', '2', '3', '4']
    ['1', '2', '3', '45']
    ['1', '2', '34', '56']
    ['1', '23', '45', '67']
    ['12', '34', '56', '78']
    ['12', '34', '56', '789']
    

    【讨论】:

    • 当我使用该函数并复制打印结果时,我得到以下结果:['1', '2', '3', '4'], ['12', '3' , '4', '5'], ['12', '34', '5', '6'], ['12', '34', '56', '7'], ['12' , '34', '56', '78'], ['123', '45', '67', '89'].
    • @AustinB 请在复制+粘贴之前完整阅读答案。
    • 啊,谢谢,我现在很累,只需要快速完成我的项目的一部分。感谢您的帮助。
    • This 更老、更流行、类似的问题最近才引起我的注意。特别是,这里的答案与链接问题中的this answer 在精神上或多或少相同。
    【解决方案2】:

    Ahsan 答案的变体应正确分布到序列末尾的其余部分:

    from itertools import accumulate
    
    def split(s, parts):
        s = str(s)
        r, rem = divmod(len(s), parts)
        norem = parts - rem
        counts = [r]*norem + [r+1]*rem
        # Prepend 0 to counts only for accumulate to start from 0
        return [s[start:start+cnt] for start, cnt in zip(accumulate([0] + counts), counts)]
    

    【讨论】:

      【解决方案3】:

      选择的答案有其优势,但我以更直接的方式做到了:

      def chunk(s, n):
          return [s[i:i+n] for i in range(0, len(s), n)]
      
      def split(s0, numberOfChunks):
          s = ('0' * max(0, numberOfChunks - len(s0))) + s0
          sizeOfChunk = len(s) / numberOfChunks
          numberOfSmallChunks = numberOfChunks - len(s) % numberOfChunks
          return chunk(s[:numberOfSmallChunks * sizeOfChunk], sizeOfChunk) +
                 chunk(s[sizeOfChunk*numberOfSmallChunks:], sizeOfChunk+1)
      

      【讨论】:

        【解决方案4】:

        抱歉 - 代码错误 它按照规范工作

        def split(s, list_size):
            s = str(s)
            assert len(s) >= list_size, "assertion failed"
            r, rem = divmod(len(s), list_size)
            lst = []
            for i in range(list_size):
                lst.append(s[i*r:(i+1)*r])
            for j in range(rem):
                lst[-(j+1)] += s[list_size + j]
            return lst
        

        【讨论】:

        • 这将因1234567 的情况而失败。
        • 这会将整个剩余部分推入最终元素,不是吗?这些例子表明其余的分散了; 7 个项目以 4 种方式拆分产生长度为 1、2、2、2,而不是 1、1、1、4 的元素。
        • 现在bug已经修复
        • 在列表中生成了奇数个 4,并且数字似乎被“打乱”了:['1', '2', '3', '4'] ['1 ', '2', '3', '44'] ['1', '2', '35', '44'] ['1', '26', '35', '44'] [' 12', '34', '56', '78'] ['12', '34', '56', '784']
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-08
        • 2020-10-01
        • 2012-07-04
        • 1970-01-01
        • 2018-01-15
        • 1970-01-01
        相关资源
        最近更新 更多