Python 创建子列表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4501636/
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 16:02:14  来源:igfitidea点击:

Creating sublists

pythonlistgrouping

提问by Michael Puckett

The opposite of list flattening.

与列表扁平化相反。

Given a list and a length n return a list of sub lists of length n.

给定一个列表和一个长度 n 返回一个长度为 n 的子列表的列表。

def sublist(lst, n):
    sub=[] ; result=[]
    for i in lst:
        sub+=[i]
        if len(sub)==n: result+=[sub] ; sub=[]
    if sub: result+=[sub]
    return result

An example:

一个例子:

If the list is:

如果列表是:

[1,2,3,4,5,6,7,8]

And n is:

而 n 是:

3

Return:

返回:

[[1, 2, 3], [4, 5, 6], [7, 8]]

Is there a more eloquent / concise way?

有没有更雄辩/简洁的方式?

An aside, what is preferred when appending lists to lists (in the context above):

顺便说一句,将列表附加到列表时首选的是什么(在上面的上下文中):

list1+=[list2]

Or:

或者:

list1.append(list2)

Given that (according to Summerfeild's 'Programming in Python 3') they are the same?

鉴于(根据 Summerfeild 的“Python 3 编程”)它们是一样的吗?

Thanks.

谢谢。

采纳答案by unutbu

Such a list of lists could be constructed using a list comprehension:

可以使用列表理解来构建这样的列表列表

In [17]: seq=[1,2,3,4,5,6,7,8]
In [18]: [seq[i:i+3] for i in range(0,len(seq),3)]
Out[18]: [[1, 2, 3], [4, 5, 6], [7, 8]]

There is also the grouper idiom:

还有石斑鱼成语

In [19]: import itertools
In [20]: list(itertools.izip_longest(*[iter(seq)]*3))
Out[20]: [(1, 2, 3), (4, 5, 6), (7, 8, None)]

but note that missing elements are filled with the value None. izip_longestcan take a fillvalueparameter as well if something other than None is desired.

但请注意,缺失的元素用值 None 填充。如果需要 None 以外的其他参数,izip_longest也可以采用fillvalue参数。



list1+=[list2]-- noting the brackets this time -- is equivalent to list1.append(list2). My highest priority when writing code is readability, not speed. For this reason, I would go with list1.append(list2). Readability is subjective, however, and probably is influenced greatly by what idioms you're familiar with.

list1+=[list2]- 这次注意括号 - 相当于list1.append(list2). 在编写代码时,我的首要任务是可读性,而不是速度。出于这个原因,我会和list1.append(list2). 然而,可读性是主观的,并且可能受您熟悉的习语影响很大。

Happily, in this case, readability and speed seem to coincide:

令人高兴的是,在这种情况下,可读性和速度似乎是一致的:

In [41]: %timeit list1=[1,2,3]; list1.append(list2)
1000000 loops, best of 3: 612 ns per loop

In [42]: %timeit list1=[1,2,3]; list1+=[list2]
1000000 loops, best of 3: 847 ns per loop

回答by Gabriel Grant

I think this split function does what you're looking for (though it works with any iterator rather than just lists):

我认为这个 split 函数可以满足您的需求(尽管它适用于任何迭代器而不仅仅是列表):

from itertools import islice

def take(n, it):
    "Return first n items of the iterable as a list"
    return list(islice(it, n))

def split(it, size):
    it = iter(it)
    size = int(size)
    ret = take(size, it)
    while ret:
        yield ret
        ret = take(size, it)

Edit: Regarding your asside, I always use list.append(blah), as it feels more idiomatic to me, but I believe they are functionally equivalent.

编辑:关于你的旁白,我总是使用 list.append(blah),因为它对我来说更惯用,但我相信它们在功能上是等效的。

回答by NPE

How about the following (where xis your list):

以下怎么样(x你的名单在哪里):

 [x[i:i+3] for i in range(0, len(x), 3)]

This is trivial to generalize for n!=3.

这对于 泛化是微不足道的n!=3

As to your second question, they're equivalent so I think it's a matter of style. However, do make sure you're not confusing appendwith extend.

至于你的第二个问题,它们是等价的,所以我认为这是一个风格问题。但是,一定要确保你不会混淆appendextend

回答by tokland

This function can take any kind of iterable (not only sequences of known length):

此函数可以采用任何类型的可迭代对象(不仅是已知长度的序列):

import itertools

def grouper(n, it):
    "grouper(3, 'ABCDEFG') --> ABC DEF G"
    it = iter(it)
    return iter(lambda: list(itertools.islice(it, n)), [])

print(list(grouper(3, [1,2,3,4,5,6,7,8,9,10])))
# [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]

回答by psihodelia

I know, it looks like a brainfwor, but is works:

我知道,它看起来像脑残,但确实有效:

>>> a = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
>>> n = 3
>>> [i for j in [[a[t:t+n] for x in a[:1:t+1] if (t%n)==False] for t in range(len(a))] for i in j]
[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15]]

>>> n = 4
>>> [i for j in [[a[t:t+n] for x in a[:1:t+1] if (t%n)==False] for t in range(len(a))] for i in j]
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15]]

回答by tsvikas

For some specific cases, it might be useful to use the numpy package. In this package you have a reshaperoutine:

对于某些特定情况,使用 numpy 包可能很有用。在这个包中,你有一个重塑例程:

import numpy as np
x = np.array([1,2,3,4,5,6])
np.reshape(x, (-1,3))

However, this solution won't pad your list, if it's not a multiply of n.

但是,如果它不是 n 的乘积,则此解决方案不会填充您的列表。

回答by vishes_shell

Have you heard of boltons?

你听说过boltons吗?

Boltonsis a set of pure-Python utilities in the same spirit as — and yet conspicuously missing from — the the standard library

Boltons是一组与标准库具有相同精神但明显缺失的纯 Python 实用程序

It has what you want, built-in, called chunked

它有你想要的,内置的,叫做 chunked

from boltons import iterutils

iterutils.chunked([1,2,3,4,5,6,7,8], 3)

Output:

输出:

[[1, 2, 3], [4, 5, 6], [7, 8]]

And whats more attractivein boltonsis that it has chunkedas an iterator, called chunked_iter, so you don't need to store the whole thing in memory. Neat, right?

和什么更吸引人boltons是,它chunked作为一个迭代器,叫chunked_iter,所以你并不需要保存在内存中的整个事情做。整洁,对吧?