问题
Given (any) list of words lst
I should divide it into 10 equal parts.
x = len(lst)/10
how to give these parts variable names?
In the output I need 10 variables (part1, part2... part10
) with x
number of words in it.
回答1:
One-liner returning a list of lists, given a list and the chunk size:
>>> lol = lambda lst, sz: [lst[i:i+sz] for i in range(0, len(lst), sz)]
Testing:
>>> 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]]
Update:
I think the question is really asking is a function which, given a list and a number, returns a list containing $(number) lists, with the items of the original list evenly distributed. So your example of lol(x, 7) should really return [[20,21,22], [23,24,25], [26,27], [28,29], [30,31], [32,33], [34,35]]. – markrian
Well, in this case, you can try:
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
I'm sure this can be improved but I'm feeling lazy. :-)
>>> slice_list(x, 7)
[[20, 21, 22], [23, 24, 25],
[26, 27], [28, 29],
[30, 31], [32, 33],
[34, 35]]
回答2:
See this question for how to generate equal chunks of a list. Then, if you really need them in separate variables, you can do:
part1, part2, ..., part10 = (part for part in chunks(lst, len(lst)/10))
But I would recommend making the code more general, instead of hardcoding it to 10 parts.
回答3:
I'll write this code so you learn the technique, but you shouldn't do this. The point of container datatypes like list
and set
is that you can have arbitrary contents without having to make variables for each elements. So,
Don't do this
>>> 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]
(The chunks
recipe is from Ned Batchelder's answer in the linked question. The reason you shouldn't do this is that modifying locals
(or indeed globals
or vars
) is not good practice: it causes hard-to-determine behaviour and possibly very nasty bugs.
回答4:
If you don't need to enforce contiguous pieces of output elements, then the following simple snippet will do the job:
def 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)
]
Basically the code is grouping elements based on modulo residues. And because of exactly that, the elements in the output list will not be contiguous. For example, if the input is range(21)
, instead of
[[0, 1, 2, 3, 4, 5],[6, 7, 8, 9, 10],[11, 12, 13, 14, 15],[16, 17, 18, 19, 20]]
you would get
[[0, 4, 8, 12, 16, 20],[1, 5, 9, 13, 17],[2, 6, 10, 14, 18],[3, 7, 11, 15, 19]]
Hope it helps.
回答5:
To achieve the same result as Paulo's update (divide a list into n chunks with size only differing by 1), the following is an elegant solution using recursion.
def divide(lst, n):
p = len(lst) // n
if len(lst)-p > 0:
return [lst[:p]] + divide(lst[p:], n-1)
else:
return [lst]
Example:
lst = list(range(13))
print divide(lst,5) # [[0, 1], [2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
回答6:
Use tuple/list a result - the most reasonable approach
If you need to define new variables, you can
- use
setattr
and add new attributes to anyobject
. It is safe since you won't overwrite existing variables:res = object() ... setattr(res, "part"+index, part_generated)
- add generated variables to
locals()
orglobals()
dictionary depending on the context your code is running in.
回答7:
Seen several solutions, but couldn't help post mine:
# 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)
Can probably be summarized further, of course, but I think this way it is clear to read.
来源:https://stackoverflow.com/questions/4119070/how-to-divide-a-list-into-n-equal-parts-python