循环向量旋转的Python实现

时间:2019-01-08 20:05:45

标签: python

我得到了一个列表a = [1, 0, 0, 1, 0]

我现在要做的是定义一个函数,该函数将列表as作为输入,其中s是我要移动的每个条目的位置数右边的列表。最右边的条目将移至列表的开头。

这意味着函数shift(a, 2)应该返回r = [1, 0, 1, 0, 0]

我得到了一个我不理解的解决方案:

def shift(a, s):
    r = []
    for i in range(len(a)):
        r.append(a[(i-s) % len(a)])
    return r

第一个问题:尽管我们向右移动,但我们减去了移动次数s

第二个问题:取模运算符的目的是什么?

有人可以在初学者水平上向我解释一下吗?

2 个答案:

答案 0 :(得分:0)

取模运算符的作用是确保您尝试访问的所有索引都在数组范围内。因此,在您的示例中,s=2a=[1, 0, 0, 1, 0]. So going through the for`一步一步循环:

r.append(a[(0-2) % len(a)])
r.append(a[(1-2) % len(a)])
...
r.append(a[(4-2) % len(a)])

在示例中,len(a)=5。在第一行中,它的计算结果为r.append(a[-2 % 5]),如果要计算,则为3。因此,它首先将a[3]附加到r,即1

下一步,它的计算结果为r.append(a[-1 % 5]),即4,因此a[4]被附加。

然后在下一步中,它变为r.append(a[0 % 5]),即a[0]。从那时起,模运算符什么都不做,其行为就像您期望的那样。

答案 1 :(得分:0)

由于您想对已经提供的解决方案进行解释,因此我在下面进行了评论。最困难的部分是取模,您可能需要阅读以下内容,以了解python如何处理对负数(link)进行取模操作

def shift(a, s):
    # Initialize an empty list to be the result
    r = []
    # Iterate through the list by index
    for i in range(len(a)):
        # i - s will give you a positive number or a negative number
        # if negative, running modulo will do a true-modulo to give the correct index. Not very readable in my opinion
        r.append(a[(i-s) % len(a)])
    return r

在我看来,我会从列表切片中生成一个新列表,因为它更加Python化且更具可读性。

def shift_mine(a, s):
    # if shifting more than the length of the list, just reduce it to the remainder
    s = s % len(a)
    # concatenate the s-from-the-end items with the beginning-to-the-s-item
    return a[s*-1:]+a[:s*-1]