【问题标题】:Split lists into chunk based of index of another list根据另一个列表的索引将列表拆分为块
【发布时间】:2020-01-14 21:08:25
【问题描述】:

我想使用另一个列表的值作为要拆分的范围,将一个列表拆分为多个块。

indices = [3, 5, 9, 13, 18]
my_list = ['a', 'b', 'c', ..., 'x', 'y', 'z']

所以基本上,从范围中拆分 my_list:

my_list[:3], mylist[3:5], my_list[5:9], my_list[9:13], my_list[13:18], my_list[18:]

我尝试将索引分成 2 块,但结果不是我需要的。

[indices[i:i + 2] for i in range(0, len(indices), 2)]

我的实际列表长度是 1000。

【问题讨论】:

    标签: python list indexing chunks


    【解决方案1】:

    使用itertools.teepairwise 的一种方式:

    from itertools import tee
    
    def pairwise(iterable):
        "s -> (s0,s1), (s1,s2), (s2, s3), ..."
        a, b = tee(iterable)
        next(b, None)
        return zip(a, b)
    
    chunks = [my_list[i:j] for i, j in pairwise([0, *indices, len(my_list)])]
    print(chunks)
    

    输出:

    [['a', 'b', 'c'],
     ['d', 'e'],
     ['f', 'g', 'h', 'i'],
     ['j', 'k', 'l', 'm'],
     ['n', 'o', 'p', 'q', 'r'],
     ['s', 't', 'u', 'v', 'w', 'x', 'y', 'z']]
    

    如果numpy 是一个选项,请使用numpy.array_split,这意味着:

    import numpy as np
    
    np.array_split(my_list, indices)
    

    输出:

    [array(['a', 'b', 'c'], dtype='<U1'),
     array(['d', 'e'], dtype='<U1'),
     array(['f', 'g', 'h', 'i'], dtype='<U1'),
     array(['j', 'k', 'l', 'm'], dtype='<U1'),
     array(['n', 'o', 'p', 'q', 'r'], dtype='<U1'),
     array(['s', 't', 'u', 'v', 'w', 'x', 'y', 'z'], dtype='<U1')]
    

    【讨论】:

      【解决方案2】:

      你也可以使用简单的python来做到这一点。

      数据

      indices = [3, 5, 9, 13, 18]
      my_list = list('abcdefghijklmnopqrstuvwxyz')
      

      解决方案

      使用列表理解。

      [(my_list+[''])[slice(ix,iy)] for ix, iy in zip([0]+indices, indices+[-1])]
      

      输出

      [['a', 'b', 'c'],
       ['d', 'e'],
       ['f', 'g', 'h', 'i'],
       ['j', 'k', 'l', 'm'],
       ['n', 'o', 'p', 'q', 'r'],
       ['s', 't', 'u', 'v', 'w', 'x', 'y', 'z']]
      

      检查是否提取了正确的索引顺序

      dict(((ix,iy), (my_list+[''])[slice(ix,iy)]) for ix, iy in zip([0]+indices, indices+[-1]))
      

      输出

      {(0, 3): ['a', 'b', 'c'],
       (3, 5): ['d', 'e'],
       (5, 9): ['f', 'g', 'h', 'i'],
       (9, 13): ['j', 'k', 'l', 'm'],
       (13, 18): ['n', 'o', 'p', 'q', 'r'],
       (18, -1): ['s', 't', 'u', 'v', 'w', 'x', 'y', 'z']}
      

      【讨论】:

      • 我认为您的解决方案不正确,因为 z 字符丢失了。
      • @Leo77 谢谢你的指出。更新了解决方案。现在它也应该给你'z'
      • 1.你不需要使用 slice,你可以使用 my_list[ix : iy] 代替。 2.然后切片列表None可以作为索引:my_list[ix:]和my_list[ix:None]是等价的。结果,你会得到这样的东西:[my_list[i: j] for i, j in zip([0] + indices, indices + [None])]
      【解决方案3】:

      可以使用itertools.zip_longest

      [my_list[a:b] for a,b in it.zip_longest([0]+indices, indices)]
      

      [['a', 'b', 'c'],
       ['d', 'e'],
       ['f', 'g', 'h', 'i'],
       ['j', 'k', 'l', 'm'],
       ['n', 'o', 'p', 'q', 'r'],
       ['s', 't', 'u', 'v', 'x', 'y', 'z']]
      

      一点代码高尔夫的乐趣:

      map(my_list.__getitem__, map(lambda s: slice(*s), it.zip_longest([0]+indices, indices)))
      

      【讨论】:

        猜你喜欢
        • 2015-12-13
        • 2023-02-23
        • 2020-05-02
        • 1970-01-01
        • 2017-12-08
        • 1970-01-01
        • 2013-09-05
        • 2021-05-23
        • 2018-09-24
        相关资源
        最近更新 更多