我正在尝试做以下事情..
我有一个n个元素的列表。我希望将此列表拆分为32个单独的列表,这些列表包含越来越多的元素,因为我们将朝向原始列表的末尾。例如来自:
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
我想得到这样的东西:
b = [[1],[2,3],[4,5,6,7],[8,9,10,11,12]]
我已经为包含1024个元素的列表完成了以下操作:
for i in range (0, 32):
c = a[i**2:(i+1)**2]
b.append(c)
但我愚蠢地努力寻找一种可靠的方法来为其他数字(如256,512,2048或其他数量的列表而不是32位)执行此操作。
答案 0 :(得分:1)
这样的事情可以解决问题。
for i in range (0, int(np.sqrt(2*len(a)))):
c = a[i**2:min( (i+1)**2, len(a) )]
b.append(c)
不是非常pythonic但是做你想要的。
def splitList(a, n, inc):
"""
a list to split
n number of sublist
inc ideal difference between the number of elements in two successive sublists
"""
zr = len(a) # remaining number of elements to split into sublists
st = 0 # starting index in the full list of the next sublist
nr = n # remaining number of sublist to construct
nc = 1 # number of elements in the next sublist
#
b=[]
while (zr/nr >= nc and nr>1):
b.append( a[st:st+nc] )
st, zr, nr, nc = st+nc, zr-nc, nr-1, nc+inc
#
nc = int(zr/nr)
for i in range(nr-1):
b.append( a[st:st+nc] )
st = st+nc
#
b.append( a[st:max(st+nc,len(a))] )
return b
# Example of call
# b = splitList(a, 32, 2)
# to split a into 32 sublist, where each list ideally has 2 more element
# than the previous
答案 1 :(得分:1)
总是这样。
>>> def log_list(l):
if len(l) == 0:
return [] #If the list is empty, return an empty list
new_l = [] #Initialise new list
new_l.append([l[0]]) #Add first iteration to new list inside of an array
for i in l[1:]: #For each other iteration,
if len(new_l) == len(new_l[-1]):
new_l.append([i]) #Create new array if previous is full
else:
new_l[-1].append(i) #If previous not full, add to it
return new_l
>>> log_list([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
[[1], [2, 3], [4, 5, 6], [7, 8, 9, 10]]
答案 2 :(得分:1)
使用iterator
,for
循环enumerate
和itertools.islice
:
import itertools
def logsplit(lst):
iterator = iter(lst)
for n, e in enumerate(iterator):
yield itertools.chain([e], itertools.islice(iterator, n))
适用于任意数量的元素。例如:
for r in logsplit(range(50)):
print(list(r))
输出:
[0]
[1, 2]
[3, 4, 5]
[6, 7, 8, 9]
... some more ...
[36, 37, 38, 39, 40, 41, 42, 43, 44]
[45, 46, 47, 48, 49]
事实上,这与this problem非常相似,只是它使用enumerate
来获取可变的块大小。
答案 3 :(得分:1)
这非常混乱,但完成工作。请注意,如果您以对数方式对列表进行切片,那么您最初会获得一些空箱。您的示例给出了算术索引序列。
from math import log, exp
def split_list(_list, divs):
n = float(len(_list))
log_n = log(n)
indices = [0] + [int(exp(log_n*i/divs)) for i in range(divs)]
unfiltered = [_list[indices[i]:indices[i+1]] for i in range(divs)] + [_list[indices[i+1]:]]
filtered = [sublist for sublist in unfiltered if sublist]
return [[] for _ in range(divs- len(filtered))] + filtered
print split_list(range(1024), 32)
修改:查看评论后,这里有一个可能符合您需求的示例:
def split_list(_list):
copy, output = _list[:], []
length = 1
while copy:
output.append([])
for _ in range(length):
if len(copy) > 0:
output[-1].append(copy.pop(0))
length *= 2
return output
print split_list(range(15))
# [[0], [1, 2], [3, 4, 5, 6], [7, 8, 9, 10, 11, 12, 13, 14]]
请注意,此代码效率不高,但可以用作编写更好算法的模板。