Python 如何以循环方式重复获取列表的固定长度切片?

Python 如何以循环方式重复获取列表的固定长度切片?,python,python-3.x,slice,Python,Python 3.x,Slice,我有一张单子 我需要能够重复地获得一个固定长度的切片,但是,当切片到达末尾时,它需要继续,就像列表是循环的一样,并循环回到起点,这样,如果所需的长度是3,那么其中一个返回值将是['z','a','b'] 我已经读过一些关于循环列表和itertools的问题,例如itertools.cycle(例如一个),但是没有一个解释如何获取所述对象的切片,我尝试过,但没有成功 我的代码: ['a', 'b', 'c'] ['b', 'c', 'd'] ... # 20 line

我有一张单子

我需要能够重复地获得一个固定长度的切片,但是,当切片到达末尾时,它需要继续,就像列表是循环的一样,并循环回到起点,这样,如果所需的长度是3,那么其中一个返回值将是
['z','a','b']


我已经读过一些关于循环列表和itertools的问题,例如itertools.cycle(例如一个),但是没有一个解释如何获取所述对象的切片,我尝试过,但没有成功


我的代码:

['a', 'b', 'c']
['b', 'c', 'd']
...              # 20 lines, expected results
['w', 'x', 'y']
[]               # wanted ['x', 'y', 'z']
[]               # wanted ['y', 'z', 'a']
[]               # wanted ['z', 'a', 'b']
['a', 'b', 'c']
#我的课程的简化版
类别MyClass:
定义初始化(自):
self.all=list('abcdefghijklmnopqrstuvxyz')
self.length=len(self.all)
self.range=切片(0,3)#起始切片
def更新(自我,增量):
#当delta的值为负值时也应起作用
新开始=(self.range.start+delta)%self.length
新停止=(self.range.stop+delta)%self.length
self.range=切片(新开始、新停止)
#用自己做事情。可见。。。
@财产
def可见(自):
返回self.all[self.range]
instance=MyClass()
对于范围(27)内的i:
打印(instance.visible)
实例。更新(1)
(Python 3.7)


输出:

['a', 'b', 'c']
['b', 'c', 'd']
...              # 20 lines, expected results
['w', 'x', 'y']
[]               # wanted ['x', 'y', 'z']
[]               # wanted ['y', 'z', 'a']
[]               # wanted ['z', 'a', 'b']
['a', 'b', 'c']

上述代码的问题是,一旦
self.range.stop
达到
self.length
,它就会小于
self.range.start
,然后在
self.range.start
达到
self.length
之前不会返回任何内容,并且
self.range.stop
不再更小

如何解决这一问题,以允许切片(或如果需要,多个切片)返回列表的正确部分,即使这意味着从开始到结束都有值?如何处理:

class-MyClass:
定义初始化(自):
self.all=list('abcdefghijklmnopqrstuvxyz')
self.length=len(self.all)
self.range=切片(0,3)#起始切片
def更新(自我,增量):
#当delta的值为负值时也应起作用
新开始=(self.range.start+delta)%self.length
新停止=(self.range.stop+delta)%self.length
self.range=切片(新开始、新停止)
#用自己做事情。可见。。。
@财产
def可见(自):
如果self.range.start>self.range.stop:
范围_1=切片(self.range.start、self.length)
range_2=切片(0,self.range.stop)
返回self.all[range_1]+self.all[range_2]
返回self.all[self.range]

下面是一个使用python库的解决方案:

from itertools import islice, cycle
from collections import deque

def cycled_slice(it, size):
    c = cycle(it)
    d = deque(islice(c, size), size)

    for x in c:
        yield list(d)
        d.append(x)

# demo

n = 0
for x in cycled_slice('abcdefg', 3):
    print(''.join(x))
    n += 1
    if n > 10:
        break
其思想是创建一个循环无限的迭代器:
abc->abcabc…
,用第一个块(
islice
)填充一个
deque
(固定长度列表),然后重复地将下一个元素附加到deque并
生成其内容

文件:


您可以如下修改可见的

@property
def visible(self):
    return list(islice(cycle(self.all),self.range.start, self.range.start+3))
您还需要导入
itertools
模块:

from itertools import cycle, islice

谢谢你的回答@georg!正如我所需要的,它是有效的。然而,皮埃尔五世的回答更适合我的情况。我相信这会有帮助。