首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >更快地将列表划分为块的方法

更快地将列表划分为块的方法
EN

Stack Overflow用户
提问于 2018-07-17 00:34:23
回答 3查看 138关注 0票数 1

我有一个需要分成块的dict列表:

代码语言:javascript
复制
input_size = len(input_rows)  # num of dicts
slice_size = int(input_size / 4)  # size of each chunk
remain = input_size % 4  # num of remaining dicts which cannot be divided into chunks
result = []  # initializes the list for containing lists of dicts
iterator = iter(input_rows)  # gets a iterator on input
for i in range(4):
    result.append([])  # creates an empty list as an element/block in result for containing rows for each core
    for j in range(slice_size):
        result[i].append(iterator.__next__())  # push in rows into the current list
    if remain:
        result[i].append(iterator.__next__())  # push in one remainder row into the current list
        remain -= 1

input_rows包含一个dict列表,将其划分为4个区块/切片;如果有任何剩余的dict不能平均划分为4个区块,则这些剩余的dict将被放入其中的一些区块中。一个列表(result)用于包含每个块,而每个块又包含一个dict列表。

我想知道如何以一种更有效的方式做这件事。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-07-18 23:24:07

看起来这不会很快作为副本关闭,所以我已经调整了tixxit’s great answer from 2010来解决这个问题,将他的生成器转换为列表理解,并希望使事情更容易理解。

代码语言:javascript
复制
chunks = 4
quot, rem = divmod(len(input_rows), chunks)
divpt = lambda i: i * quot + min(i, rem)
return [input_rows[divpt(i):divpt(i+1)] for i in range(chunks)]

下面的测试框架显示,生成的代码生成的结果与OP的代码完全相同。

代码语言:javascript
复制
def main():
    for top in range(1, 18):
        print("{}:".format(top))
        input_list = list(range(1, top + 1))

        daiyue = chunkify_daiyue(input_list[:])
        print('daiyue: {}'.format(daiyue))

        zych = chunkify_zych(input_list[:])
        match = 'Same' if (zych == daiyue) else 'Different'
        print('Zych:   {}   {}'.format(zych, match))

        print('')


def chunkify_daiyue(input_rows):
    "Divide into chunks with daiyue's code"

    input_size = len(input_rows)  # num of dicts
    slice_size = int(input_size / 4)  # size of each chunk
    remain = input_size % 4  # num of remaining dicts which cannot be divided into chunks

    result = []  # initializes the list for containing lists of dicts
    iterator = iter(input_rows)  # gets a iterator on input

    for i in range(4):
        # creates an empty list as an element/block in result for
        # containing rows for each core
        result.append([])

        for j in range(slice_size):
            # push in rows into the current list
            result[i].append(iterator.__next__())
        if remain:
            # push in one remainder row into the current list
            result[i].append(iterator.__next__())
            remain -= 1

    return result


def chunkify_zych(input_rows):
    "Divide into chunks with Tom Zych's code"

    chunks = 4
    quot, rem = divmod(len(input_rows), chunks)
    divpt = lambda i: i * quot + min(i, rem)
    return [input_rows[divpt(i):divpt(i+1)] for i in range(chunks)]


if __name__ == '__main__':
    main()
票数 1
EN

Stack Overflow用户

发布于 2018-07-17 04:12:16

使用标准库

代码语言:javascript
复制
R = list()
L = list(range(10))

remainder = int(len(L) % 4)
chunk_size = int(len(L) / 4)
position = 0

while position < len(L):
    this_chunk = chunk_size
    if remainder:
        this_chunk += 1
        remainder -= 1
    R.append(L[position:this_chunk + position])
    position += this_chunk

print(R)
[[0, 1, 2], [3, 4, 5], [6, 7], [8, 9]]

这应该会更快,因为你的迭代和插入要少得多。在这种情况下,您实际上只需要抓取4个切片,然后根据列表元数据的计算插入4次……

此外,这是使用numpy.array_split*的具体原因:这应该更快……

代码语言:javascript
复制
>>> print(*np.array_split(range(10), 4))
[0 1 2] [3 4 5] [6 7] [8 9]

编辑:由于评论部分中的反馈和上面答案中的潜在错误(在输入列表大小小于潜在组块数量的情况下),下面是一个替代函数,它执行相同的操作,但将始终生成请求的组块数量

代码语言:javascript
复制
def array_split(input_list, chunks):
    chunk_size = int(len(input_list) / chunks)
    remainder = len(input_list) % chunks
    new_list = list()
    position = 0

    while position < len(input_list):
        this_chunk = chunk_size
        if remainder:
            this_chunk, remainder = this_chunk + 1, remainder - 1
        new_list.append(input_list[position:this_chunk + position])
        position += this_chunk

    new_list.extend([[] for _ in range(chunks - len(new_list))])

    return new_list

def unit_test():
    L = [1, 2]
    print(array_split(L, 4))

    L = list(range(13))
    print(array_split(L, 3))

    L = list(range(22))
    print(array_split(L, 5))

>>> unit_test()
[[1], [2], [], []]
[[0, 1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12, 13], [14, 15, 16, 17], [18, 19, 20, 21]]
票数 2
EN

Stack Overflow用户

发布于 2018-07-17 02:50:52

代码语言:javascript
复制
myList = [1,2,3,4,5,6,9]
numOfChunks = 2
newList = []

for i in range(0, len(myList), numOfChunks):
  newList.append(myList[i:i + numOfChunks])

print (newList) # [[1, 2], [3, 4], [5, 6], [9]]
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51366397

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档