将列表拆分为子列表中的n个项目,并添加余数

时间:2014-01-08 21:05:46

标签: python list split subset

我昨晚问了这个问题,但我的措辞很差。 我正在尝试列出:

['milk','eggs','beef','oranges','dog food','chips','soda','bread']

并将其拆分为每个n的列表,任何剩余部分都需要均匀地添加到列表中......因此结果将是n = 3

[['milk','eggs','beef'],['oranges','dog food','chips']]

余下的['soda','bread']会给我最终的结果:

[['milk','eggs','beef','soda'],['oranges','dog food','chips','bread']]

订单无关紧要。

7 个答案:

答案 0 :(得分:4)

简短而有效的解决方案:

def splitList (lst, n):
    it = iter(lst)
    new = [[next(it) for _ in range(n)] for _ in range(len(lst) // n)]

    for i, x in enumerate(it):
        new[i].append(x)

    return new
>>> lst = ['milk', 'eggs', 'beef', 'oranges', 'dog food', 'chips', 'soda', 'bread']
>>> splitList(lst, 3)
[['milk', 'eggs', 'beef', 'soda'], ['oranges', 'dog food', 'chips', 'bread']]
>>> splitList([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3)
[[1, 2, 3, 10], [4, 5, 6], [7, 8, 9]]

这首先创建了一个我们用于一切的单个迭代器;所以我们总共只在列表上循环一次。将创建的子列表数量为len(lst) // n(整数除法向下舍入),对于每个子列表,我们从迭代器中获取n个值。

之后,剩下的项目仍将保留在迭代器中,因此我们可以简单地迭代其余项目,并将它们直接附加到子列表。

答案 1 :(得分:1)

我相信下面的代码非常简单,对您有用。 请注意,它需要more_itertools模块

from more_itertools import chunked

x = ['milk','eggs','beef','oranges','dog food','chips','soda','bread']

def foo(lst,num):
    chunk = list(chunked(lst,num))

    if len(chunk[-1]) == num:
        return chunk

    for i,val in enumerate(chunk[-1]):
        chunk[i].append(val)
    del chunk[-1]

    return chunk

ans = foo(x,3)
# [['milk', 'eggs', 'beef', 'soda'], ['oranges', 'dog food', 'chips', 'bread']]

代码使用more_itertools中的chunked方法将列表分成大小为n的子列表(在示例3中),其中任何余数都在最终子列表中。然后,我迭代这个最终的子列表,并将其元素附加到现有的子列表中。然后删除最终的子列表。

答案 2 :(得分:1)

对于列表a,您可以按n获取长度floor(len(a) / n)最短的群组数。

def split(a, minSize):
    numGroups = int(len(a) / minSize)
    return [a[i::numGroups] for i in range(numGroups)]

答案 3 :(得分:0)

我已经开始回答你的问题了。我仍然有点不清楚添加列表的剩余部分,所以这可能需要在某个时候进行修订。 如果以下功能符合您的目的,请与我们联系。

groceryList = ['milk', 'eggs', 'beef', 'oranges', 'dog food', 'chips', 'soda', 'bread']
outlist = []
listLength = len(groceryList)
modulus = listLength // 3
remainder = listLength % 3
print listLength, modulus, remainder
ending = 0
while modulus >= 1:
    outlist.append(groceryList[ending:ending+3])
    ending += 3
    modulus -= 1

print "value of ending", ending
outlistcounter = 0
if remainder > 0:
    while remainder != 0:
        outlist[outlistcounter].extend(groceryList[ending:ending+1])
        outlistcounter += 1
        remainder -= 1
        ending += 1
print outlist

答案 4 :(得分:0)

试试这个:

def split_list(lst, n):
    result = []
    # split off elements in groups of `n`
    i = 0
    while i+n <= len(lst):
        result.append([])
        for k in range(n):
            result[-1].append(lst[i+k])
        i += n
    # add the remainder to the groups
    j = 0
    while i < len(lst):
        result[j].append(lst[i])
        i += 1
        j += 1
        j %= len(result)
    return result

lst = ['milk','eggs','beef','oranges','dog food','chips','soda','bread']
for i in range(1, len(lst)):
    print(i, split_list(lst, i))

结果:

1 [['milk'], ['eggs'], ['beef'], ['oranges'], ['dog food'], ['chips'], ['soda'], ['bread']]
2 [['milk', 'eggs'], ['beef', 'oranges'], ['dog food', 'chips'], ['soda', 'bread']]
3 [['milk', 'eggs', 'beef', 'soda'], ['oranges', 'dog food', 'chips', 'bread']]
4 [['milk', 'eggs', 'beef', 'oranges'], ['dog food', 'chips', 'soda', 'bread']]
5 [['milk', 'eggs', 'beef', 'oranges', 'dog food', 'chips', 'soda', 'bread']]
6 [['milk', 'eggs', 'beef', 'oranges', 'dog food', 'chips', 'soda', 'bread']]
7 [['milk', 'eggs', 'beef', 'oranges', 'dog food', 'chips', 'soda', 'bread']]

但这是一件奇怪的事情,所以我想知道你是否可能不会从错误的角度攻击你的问题。

答案 5 :(得分:0)

这适用于您似乎要求的内容:

def f(x, n):

    if n > len(x):
        return

    y = [x[i: i + n] for i in range(0, len(x), n)]  #split the list up into lists by n

    if len(y[-1]) != n:  #if there is a remainder
        remainder = y[-1]   
        y = y[:-1]

        count = 0
        while remainder:  #while remainder is not an empty list
            for lst in y:
                lst.append(remainder.pop())  #pop the remaining items into each of the other lists 
                count += 1
    return y

示例输出:

myList =['milk','eggs','beef','oranges','dog food','chips','soda','bread']

print f(myList, 3)

[['milk', 'eggs', 'beef', 'bread'], ['oranges', 'dog food', 'chips', 'soda']]

答案 6 :(得分:0)

像上面这样可能会更短一点

def Matts_list( l, n ):
    return_list = [ l[i:i + n] for i in range( 0, len( l ), n ) ]
    # last list isn't n long
    if len( return_list[-1] ) != n :
        last = return_list.pop()
        for i in range( 0, len( last ) ):
            return_list[i % len( return_list )].append( last[i] )
    return return_list