如何将列表分成n个相等的部分,python

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4119070/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 14:21:23  来源:igfitidea点击:

How to divide a list into n equal parts, python

pythonlistdivide

提问by Gusto

Given (any) list of words lstI should divide it into 10 equal parts.

给定(任何)单词列表,lst我应该将其分成 10 个相等的部分。

x = len(lst)/10

how to give these parts variable names?

如何给这些部分变量名?

In the output I need 10 variables (part1, part2... part10) with xnumber of words in it.

在输出中,我需要 10 个变量 ( part1, part2... part10),其中x包含单词数。

回答by tsg

See this questionfor 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.

但我建议让代码更通用,而不是将其硬编码为 10 个部分。

回答by Katriel

I'll write this code so you learn the technique, but you shouldn't do this. The point of container datatypes like listand setis that you can have arbitrary contents without having to make variables for each elements. So,

我将编写此代码以便您学习该技术,但您不应该这样做。集装箱数据类型一样的点list,并set是,你可以有任意内容,而无需进行变量的每个元素。所以,

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 chunksrecipe is from Ned Batchelder's answerin the linked question. The reason you shouldn't do this is that modifying locals(or indeed globalsor vars) is not good practice: it causes hard-to-determine behaviour and possibly very nasty bugs.

chunks配方来自Ned Batchelder在链接问题中的回答。您不应该这样做的原因是修改locals(或实际上globalsvars)不是好的做法:它会导致难以确定的行为,并且可能会导致非常讨厌的错误。

回答by Paulo Scardine

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

我认为问题真正要问的是一个函数,它给定一个列表和一个数字,返回一个包含 $(number) 列表的列表,原始列表的项目均匀分布。所以你的 lol(x, 7) 的例子应该真的返回 [[20,21,22], [23,24,25], [26,27], [28,29], [30,31], [32] ,33], [34,35]]。– 马克里安

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]]

回答by khachik

Use tuple/list a result - the most reasonable approach

使用元组/列出结果 - 最合理的方法

If you need to define new variables, you can

如果你需要定义新的变量,你可以

  1. use setattrand add new attributes to any object. It is safe since you won't overwrite existing variables:
    res = object()
    ...
    setattr(res, "part"+index, part_generated)
    
  2. add generated variables to locals()or globals()dictionary depending on the context your code is running in.
  1. 使用setattr并将新属性添加到任何object. 这是安全的,因为您不会覆盖现有变量:
    res = object()
    ...
    setattr(res, "part"+index, part_generated)
    
  2. 根据您的代码运行的上下文,将生成的变量添加到locals()globals()字典中。

回答by jorgehumberto

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.

或许可以进一步总结,当然,但我认为这样读起来很清楚。

回答by Mai

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

基本上代码是基于模残差对元素进行分组。正因为如此,输出列表中的元素不会是连续的。例如,如果输入是range(21),而不是

[[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.

希望能帮助到你。

回答by henneray

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.

为了获得与 Paulo 的更新相同的结果(将列表分成 n 个大小仅相差 1 的块),以下是使用递归的优雅解决方案。

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]]