gpt4 book ai didi

Python 以递增的大小对列表中的元素进行分组

转载 作者:太空狗 更新时间:2023-10-29 21:18:30 26 4
gpt4 key购买 nike

my_list = [my_list[int((i**2 + i)/2):int((i**2 + 3*i + 3)/2)] for i in range(int((-1 + (1 + 8*len(my_list))**0.5)/2))]

有没有比这更简洁的解决方案来将列表的元素分组到大小递增的子组中?

例子:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] --> [[1], [2, 3], [4, 5, 6], [7, 8, 9, 10]]
[1, 2, 3, 4] --> [[1], [2, 3]]
[1, 2, 3, 4, 5, 6] --> [[1], [2, 3], [4, 5, 6]]

编辑

这是 timeit 的结果:

from timeit import Timer
from itertools import count

def martijn(it):
it = iter(it)
return list([next(it) for _ in range(s)] for s in count(1))

def mathematical(it):
upper_bound = int(((1 + 8*len(it))**0.5 + 1)//2)
return [it[i*(i-1)//2:i*(i+1)//2] for i in range(1, upper_bound)]

def time(test, n):
a = Timer(lambda: martijn(test)).timeit(n)
b = Timer(lambda: mathematical(test)).timeit(n)
return round(a, 3), round(b, 3)

>>> for i in range(8):
loops = 10**max(0, (6-i))
print(time([n for n in range(10**i)], loops), loops)
(6.753, 4.416) 1000000
(1.166, 0.629) 100000
(0.366, 0.123) 10000
(0.217, 0.036) 1000
(0.164, 0.017) 100
(0.157, 0.017) 10
(0.167, 0.021) 1
(1.749, 0.251) 1
>>> for i in range(8):
loops = 10**max(0, (6-i))
print(time(range(10**i), loops), loops)
(6.721, 4.779) 1000000
(1.184, 0.796) 100000
(0.367, 0.173) 10000
(0.218, 0.051) 1000
(0.202, 0.015) 100
(0.178, 0.005) 10
(0.207, 0.002) 1
(1.872, 0.005) 1

最佳答案

使用生成器表达式:

from itertools import count

try:
_range = xrange
except NameError:
# Python 3
_range = range


def incremental_window(it):
"""Produce monotonically increasing windows on an iterable.

Only complete windows are yielded, if the last elements do not form
a complete window they are ignored.

incremental_window('ABCDEF') -> ['A'], ['B', 'C'], ['D', 'E', 'F']
incremental_window('ABCDE') -> ['A'], ['B', 'C']

"""
it = iter(it)
return ([next(it) for _ in _range(s)] for s in count(1))

演示:

>>> list(incremental_window([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]))
[[1], [2, 3], [4, 5, 6], [7, 8, 9, 10]]
>>> list(incremental_window([1, 2, 3, 4]))
[[1], [2, 3]]
>>> list(incremental_window([1, 2, 3, 4, 5, 6]))
[[1], [2, 3], [4, 5, 6]]

这是一个可以处理任何可迭代对象的生成器,包括无穷无尽的可迭代对象:

>>> from itertools import count
>>> for window in incremental_window(count()):
... print window
... if 25 in window:
... break
...
[0]
[1, 2]
[3, 4, 5]
[6, 7, 8, 9]
[10, 11, 12, 13, 14]
[15, 16, 17, 18, 19, 20]
[21, 22, 23, 24, 25, 26, 27]

可以使它成为一个带有一点欺骗的单行代码以“内联”iter() 对您的列表对象的调用:

list([next(it) for _ in _range(s)] for it in (iter(my_list),) for s in count(1))

关于Python 以递增的大小对列表中的元素进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23015438/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com