对于任意的单词列表lst
,我应该将其分成10个相等的部分。
x = len(lst)/10
如何为这些部分命名变量?
在输出中,我需要10个变量(part1、part2... part10
),每个变量中都包含x
个单词。
给定一个列表和分块大小,返回一个列表的列表的一行代码:
>>> lol = lambda lst, sz: [lst[i:i+sz] for i in range(0, len(lst), sz)]
测试:
>>> x = range(20, 36)
>>> print x
[20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35]
>>> lol(x, 4)
[[20, 21, 22, 23],
[24, 25, 26, 27],
[28, 29, 30, 31],
[32, 33, 34, 35]]
>>> lol(x, 7)
[[20, 21, 22, 23, 24, 25, 26],
[27, 28, 29, 30, 31, 32, 33],
[34, 35]]
更新:
我认为这个问题实际上是在询问一个函数,它接受一个列表和一个数字,返回一个包含$(number)个列表的列表,其中原始列表的项目被平均分配到这些列表中。因此,你的lol(x, 7)的例子应该真正返回[[20,21,22],[23,24,25],[26,27],[28,29],[30,31],[32,33],[34,35]]。- markrian
在这种情况下,你可以尝试:
def slice_list(input, size):
input_size = len(input)
slice_size = input_size / size
remain = input_size % size
result = []
iterator = iter(input)
for i in range(size):
result.append([])
for j in range(slice_size):
result[i].append(iterator.next())
if remain:
result[i].append(iterator.next())
remain -= 1
return result
我相信这可以改进,但懒得动手。 :-)
>>> slice_list(x, 7)
[[20, 21, 22], [23, 24, 25],
[26, 27], [28, 29],
[30, 31], [32, 33],
[34, 35]]
def divide(lst, n):
p = len(lst) // n
if len(lst)-p > 0:
return [lst[:p]] + divide(lst[p:], n-1)
else:
return [lst]
例子:
lst = list(range(13))
print divide(lst,5) # [[0, 1], [2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
part1, part2, ..., part10 = (part for part in chunks(lst, len(lst)/10))
但我建议将代码更改为更通用的形式,而不是硬编码为10个部分。
我会写这段代码让你学习技巧,但你不应该这样做。像 list
和 set
这样的容器数据类型的重点是你可以拥有任意内容而不必为每个元素创建变量。所以,
>>> def chunks(l, n):
... for i in xrange(0, len(l), n):
... yield l[i:i+n]
...
>>> for i, chunk in enumerate(chunks(range(100), 10)):
... locals()["part{0}".format(i)] = chunk
...
>>> part0
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> part1
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> part2
[20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
chunks
配方来自于 Ned Batchelder's answer 的链接问题。你不应该这样做的原因是修改 locals
(或者 globals
或者 vars
)不是一个好的实践:它会导致难以确定的行为和可能非常严重的错误。)chunks
无法将列表 l
平均分成 n
份,那么它会将 l
分成 len(l)/n + 1
份(当 len(l)%n != 0
)或者 len(l)/n
份(当 len(l)%n == 0
)。 - khachikdef even_divide(lst, num_piece=4):
return [
[lst[i] for i in range(len(lst)) if (i % num_piece) == r]
for r in range(num_piece)
]
range(21)
,输出将不会是连续的。[[0, 1, 2, 3, 4, 5],[6, 7, 8, 9, 10],[11, 12, 13, 14, 15],[16, 17, 18, 19, 20]]
[[0, 4, 8, 12, 16, 20],[1, 5, 9, 13, 17],[2, 6, 10, 14, 18],[3, 7, 11, 15, 19]]
chunk_size=5
_chunks=list(x [i:i+chunk_size]
for i in range(0, len(x ), chunk_size))
看到了几个解决方案,但还是想分享我的:
# List
lst = range(103)
# number of slices
nSlices = 10
# splitted list
slices = [len(lst) // (nSlices)] * nSlices
# but points are still missing!
remainder = len(lst)-sum(slices)
# split missing points across slices
slices[:remainder] = [ii + 1 for ii in slices[:remainder]]
splittedList = [lst[sum(slices[:ii]):sum(slices[:ii+1])] for ii in range(nSlices)]
print lst
print '\n'.join("{}".format(n) for n in splittedList)
当然可以进一步概括,但我认为这样阅读起来更清晰。
与 @henneray 相同,针对数据框
def divide_df(df, n):
p = len(df.index) // n # size of one part is length / parts
if len(df.index) - p > 0: # if a part of size p is still remaining
return [df.iloc[0:p]] + divide(df.iloc[p:], n-1) # one part is from start to p, recursivly divide rest into n-1 pieces
else:
return [df]
使用元组/列表作为结果 - 最合理的方法
如果需要定义新变量,您可以:
setattr
并向任何 object
添加新属性。这是安全的,因为您不会覆盖现有变量:
res = object() ... setattr(res, "part"+index, part_generated)
locals()
或 globals()
字典中。
[1,2,3,4,5,...100]
变成[1,2,3,...],[11,12,13,...],...
或者[1,11,21,...],[2,12,22,...],...
或者随机或其他方式? - kennytm