Python 3.x 将列表划分为块的更快方法
我有一个Python 3.x 将列表划分为块的更快方法,python-3.x,iterator,Python 3.x,Iterator,我有一个dicts列表,我需要分为几个部分: 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 c
dict
s列表,我需要分为几个部分:
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
s列表,将其划分为4个块/片;如果有任何剩余的dict
s不能平均分为4个块,这些剩余的dict
s将被放入一些块中。一个列表(result
)用于包含每个块,而每个块又包含一个dict
的列表
我想知道如何更有效地使用标准库
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]]
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]]
编辑:由于评论部分的反馈和上述答案中的潜在错误(在输入列表大小小于潜在块数的情况下),这里有一个替代函数,它可以做同样的事情,但始终会生成请求的块数
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]]
def数组分割(输入列表,块):
chunk\u size=int(len(输入列表)/chunk)
余数=len(输入列表)%块
新建列表=列表()
位置=0
位置>>单元测试()
[[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]]
使用标准库
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]]
编辑:由于评论部分的反馈和上述答案中的潜在错误(在输入列表大小小于潜在块数的情况下),这里有一个替代函数,它可以做同样的事情,但始终会生成请求的块数
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]]
def数组分割(输入列表,块):
chunk\u size=int(len(输入列表)/chunk)
余数=len(输入列表)%块
新建列表=列表()
位置=0
位置>>单元测试()
[[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]]
看起来这个副本不会很快被关闭,所以我
适应这个问题,转换
我希望他的生成器能够帮助你理解并使事情变得更简单
理解
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的代码完全相同的结果
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()
看起来这个不会很快作为副本关闭,所以我 适应这个问题,转换 我希望他的生成器能够帮助你理解并使事情变得更简单 理解
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的代码完全相同的结果
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()
如果元素计数为7或8,则此操作会正常工作。对于其他数字,即使你调整了NumofChunk,它也不会。我没有得到你的回答,你能给我一个你正在尝试的例子吗;你最后只剩下三块了。用九块试试,你会得到五块。或者,九个
numockhunks=3
,则得到三个块。不是OP所要求的。如果元素计数为7或8,则此操作会正常工作。对于其他数字,即使你调整了NumofChunk,它也不会。我没有得到你的回答,你能给我一个你正在尝试的例子吗;你最后只剩下三块了。用九块试试,你会得到五块。或者,九个numockhunks=3
,则得到三个块。不是OP要求的。的可能重复做了您想要的。的可能重复做了您想要的。如果输入长度小于4,则与OP的代码结果略有不同,例如,OP的[[1],[2],[]],[]
与您的[[1],[2]]
相比。有些人更喜欢后者。@TomZych是的。。。答案中有几个洞,我不认为是在“如何使这更快”的范围内。理想情况下,您可以在函数中指定所需的块数,而不是硬编码的4。如果输入列表小于请求的数据块大小,则您的函数可以添加额外的列表,或者根据函数的使用情况进行放大。如果输入长度小于4,则结果与OP的代码略有不同,例如,OP的[[1]、[2]、[]
与您的[[1]、[2]]
相比。有些人更喜欢后者。@TomZych是的。。。答案中有几个洞,我不认为是在“如何使这更快”的范围内。理想情况下,您可以在函数中指定所需的块数,而不是硬编码的4。如果输入列表小于所请求的块大小,那么您的函数可以只附加额外的列表,或者根据函数的用例进行放大。