给定一个整数列表L,我需要生成所有子列表L[k:] for k in [0, len(L) - 1],而不生成副本。
我如何在 Python 中实现这一点?使用缓冲区对象?
在 Python 中,您可以使用切片L[k:]为 all kin生成子列表[0, len(L) - 1],而无需生成副本,因为 Python 中的切片会返回列表的新视图,而不是元素的副本。但是,如果您想避免切片的开销,或者想要尽可能接近地模拟此行为而不复制元素,则可以使用带索引的循环或使用itertools.islice。以下是方法:
L[k:]
k
[0, len(L) - 1]
itertools.islice
切片列表不会复制底层元素,但会创建一个引用相同元素的新列表对象。这种方法通常很高效,而且很 Pythonic。
L = [1, 2, 3, 4, 5] # Generate sublists sublists = [L[k:] for k in range(len(L))] for sublist in sublists: print(sublist)
您可以使用生成器来延迟生成子列表:
def sublists(L): for k in range(len(L)): yield L[k:] # Usage L = [1, 2, 3, 4, 5] for sublist in sublists(L): print(sublist)
itertools.islice可用于创建一个迭代器,以惰性方式生成列表的切片:
from itertools import islice def sublists(L): for k in range(len(L)): yield islice(L, k, None) # Usage L = [1, 2, 3, 4, 5] for sublist in sublists(L): print(list(sublist)) # Convert to list to print, but the iteration itself is lazy
memoryview
bytes如果您的列表由字节(即或对象)组成bytearray,则您可以使用它memoryview在列表中创建视图而无需复制:
bytes
bytearray
L = bytearray([1, 2, 3, 4, 5]) def sublists(L): mv = memoryview(L) for k in range(len(L)): yield mv[k:] # Usage for sublist in sublists(L): print(bytes(sublist)) # Convert to bytes to print, but the view is lazy
对于一般列表,使用切片或生成器(如方法 1 和 2 中所示)通常是最佳方法。itertools.islice是避免创建中间列表的另一个不错的选择。如果您的列表专门由字节组成,则memoryview可能是一种有效的选择。
在所有情况下,都不会复制基础数据,并且您仅通过引用现有数据来生成子列表。