创建子列表

发布于 2024-10-08 19:24:06 字数 657 浏览 3 评论 0原文

与列表扁平化相反。

给定一个列表和长度 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

举个例子:

如果列表是:

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

并且 n 是:

3

返回:

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

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

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

list1+=[list2]

或者:

list1.append(list2)

考虑到(根据 Summerfeild 的“Python 3 编程”)它们是相同的?

谢谢。

The opposite of list flattening.

Given a list and a length n return a list of sub lists of length 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:

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?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

零度° 2024-10-15 19:24:07

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

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

有还有 石斑鱼习语

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

但请注意,缺少的元素将用值 None 填充。 izip_longest 也可以采用 fillvalue 参数如果需要除“无”之外的其他内容。


list1+=[list2]——注意这次的括号——相当于list1.append(list2)。我写代码时最优先考虑的是可读性,
不是速度。因此,我会选择 list1.append(list2)。然而,可读性是主观的,并且可能很大程度上受到您所熟悉的习语的影响。

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

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

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_longest can take a fillvalue parameter as well if something other than None is desired.


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.

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
(り薆情海 2024-10-15 19:24:07

下面的内容怎么样(其中 x 是您的列表):

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

对于 n!=3 来说,这很简单。

至于你的第二个问题,它们是等效的,所以我认为这是风格问题。但是,请确保您没有令人困惑<代码>附加和<代码>扩展

How about the following (where x is your list):

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

This is trivial to generalize for 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 append with extend.

天赋异禀 2024-10-15 19:24:07

您听说过 boltons 吗?

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

它具有您想要的内置功能,称为分块

from boltons import iterutils

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

输出:

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

并且boltons更有吸引力的是它有分块作为迭代器,称为chunked_iter,因此您不需要存储整个事情都在记忆中。很整洁,对吧?

Have you heard of boltons?

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

It has what you want, built-in, called 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 attractive in boltons is that it has chunked as an iterator, called chunked_iter, so you don't need to store the whole thing in memory. Neat, right?

够钟 2024-10-15 19:24:07

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

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

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]]
韵柒 2024-10-15 19:24:07

我认为这个 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)

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

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

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.

凉世弥音 2024-10-15 19:24:07

对于某些特定情况,使用 numpy 包可能会很有用。在此包中,您有一个 reshape 例程:

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

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

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

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.

素年丶 2024-10-15 19:24:07

我知道,它看起来像 brainfuck,但它是有效的:

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

I know, it looks like a brainfuck, 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]]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文