假设我有一个数组foo
,包含元素[1, 2, 3]
,我想以foo
被“无限连接”后的方式检索foo
的元素。
例如,foo[0:2]
将返回(像普通列表一样):
[1, 2]
而foo[0:5]
将返回:
[1, 2, 3, 1, 2]
当使用foo[7:13]
时,将返回:
[2, 3, 1, 2, 3, 1]
Python中是否有任何数据容器或扩展模块已经方便了这种类型的访问?如果没有,那么提供这个容器的好/简单方法是什么?
假设我有一个数组foo
,包含元素[1, 2, 3]
,我想以foo
被“无限连接”后的方式检索foo
的元素。
例如,foo[0:2]
将返回(像普通列表一样):
[1, 2]
而foo[0:5]
将返回:
[1, 2, 3, 1, 2]
当使用foo[7:13]
时,将返回:
[2, 3, 1, 2, 3, 1]
Python中是否有任何数据容器或扩展模块已经方便了这种类型的访问?如果没有,那么提供这个容器的好/简单方法是什么?
恐怕你得自己实现。不过这并不难:
class cyclist(list):
def __getitem__(self, index):
return list.__getitem__(self, index % len(self))
def __getslice__(self, start, stop):
return [self[n] for n in range(start, stop)]
foo = cyclist([1, 2, 3])
print foo[0:2] # [1, 2]
print foo[7:13] # [2, 3, 1, 2, 3, 1]
print foo[0:5] # [1, 2, 3, 1, 2]
缺少一些细节,比如处理省略的切片参数、切片中的负数以及切片步长。
get_cyclic_item
和get_cyclic_slice
,而不是覆盖列表的__getitem__
和__getslice__
。a = cyclicallist([ 0, 1, 2 ])
# appending a value at the end changes an "existing" index
print a[100]
a.append(99)
print a[100]
# deleting a value changes an index preceding it
print a[100]
del a[999] # currently gives an error: IndexError: list assignment index out of range
print a[100] # even if no error, what should this print?
# hmm...
del a[100:99999]
itertools
也是一个有趣的方式来完成它...>>> from itertools import islice, cycle
>>> make_cyclic = lambda lst: lambda start, stop: list( islice( cycle( lst ), start, stop ) )
>>> make_cyclic( [ 1, 2, 3 ] )
>>> c(7, 13)
[2, 3, 1, 2, 3, 1]
class cyclicaltuple(tuple): ...
是一个不错的选择。 - shx2cyclist
:) 我认为宣布cyclist
不可变就足够了(也许可以从collections.Sequence
继承)。 - Pavel Anossov