这是比较容易实现的 - 但既然你有“条件”(我将使用这里的术语“断言”),有并发症:对于没有复制可言,所形成的结构的唯一途径可以“知道”一个项目是否在访问时检查它 - 这意味着你的索引中会出现“漏洞”。
这很容易理解给出的例子:
a = list(range(20))
b = SlicedList(a, slice(10, 20), predicate=lambda x: x%2
len(b) # will correctly report (5)
b[0] # will raise ValueError as "10" fails the predicate
# so, 0-9 are valid indexes for "b", but only the contents
# that attend the predicate will actually return a value
# you can safely iterate on b with a "for", though:
for item in b:
print(item) # (11, 13, 15, 17, 19)
迭代,但是,它应该很好地工作。
try:
from collections.abc import MutableSequence
except ImportError:
from collections import MutableSequence
class SlicedList(MutableSequence):
def __init__(self, data, slice=None, predicate=None):
self.data = data
if not slice:
slice = __builtins__.slice(0, len(data), 1)
self.slice = slice
self.predicate = predicate
def __getitem__(self, index):
if index < 0:
raise NotImplementedError("Can't use negative indexes on Sliced lists")
real_index = self.slice.start + index * (self.slice.step or 1)
item = self.data[real_index]
if self.predicate and not self.predicate(item):
raise ValueError("Item at position {} does not attend the predicate".format(index))
return item
def __setitem__(self, index, value):
...
def __delitem__(self, index):
...
def __len__(self):
if not self.predicate:
start, stop, step = self.slice.indices(len(data))
return (stop - start) // (step or 1)
count = 0
for i in range(self.slice.start, self.slice.stop, self.slice.step or 1):
if self.predicate(self.data[i]):
count += 1
return count
def __iter__(self):
for i in range(self.slice.start, self.slice.stop, self.slice.step or 1):
value =self.data[i]
if not self.predicate or self.predicate(value):
yield i
def insert(self, position, value):
...
另一个提示你是要尽快退出Python 2.7版 - 所有的现代库和框架运行好的关于Python 3和Python 2是变得非常老化,这些天。下面的代码可以同时工作,但我必须为此做出规定。
迭代器工具不会复制列表或我完全错误?但是,如果你计划删除列表中的项目,你将不得不创建一个新的列表,看看列表是不可变的,不能改变。也许看看'dicts'或[ctype.array](https://docs.python.org/2/library/ctypes.html#arrays)s - 也许你可以用这些做些什么? – Torxed
@Toxxed列表是可变的。 – roganjosh
@roganjosh对不起,你说得对。我在头脑中混合了'tuple'的列表。 – Torxed