为什么切片操作在我的 Python 代码中表现不一致?

Why does the slice operation behave inconsistently in my Python code?

提问人:Jamal 提问时间:5/30/2023 最后编辑:rr_goyalJamal 更新时间:5/31/2023 访问量:75

问:

切片操作似乎不一致。在某些情况下,slice 包含第 k 个值,有时则不包含。

rotate.py

def rotate(nums, k):
    temp = nums[0:k+1]
    del nums[0:k+1]
    nums.extend(temp)

test_rotate.py

import unittest
from rotate_array import rotate

class TestRotateArray(unittest.TestCase):
    def test_rotate_array2(self):
        nums= [-1, -100, 3, 99]
        k = 2
        expected = [3, 99, -1, -100]
        rotate(nums, k)
        self.assertListEqual(nums, expected)
    
    def test_rotate_array(self):
        nums= [1,2,3,4,5,6,7]
        k = 3
        expected = [5,6,7,1,2,3,4]
        rotate(nums, k)
        self.assertListEqual(nums, expected)

if __name__ == '__main__':
        unittest.main()

当我做nums[:k+1]时,第一个测试将失败,第二个测试将通过。 失败测试的 nums 数组:[99, -1, -100, 3]

当我使用 nums[0:k] 时,第一个通过,第二个不通过。 失败测试的 nums 数组:[4, 5, 6, 7, 1, 2, 3]

我正在研究的整个问题可以在这里找到

Python 列表 切片

评论

3赞 user2357112 5/30/2023
你正在朝着与你似乎认为的相反的方向旋转。

答:

0赞 Abdullah Faqih 5/30/2023 #1

您缺少其他索引。由于你停在 i+1 处,如果你有 k = 2 -->(0、1、2,3 除外),你将切分三个元素。

在第一种情况下,temp = [-1, -100, 3],num 将为 [99, -1, -100, 3]

0赞 rr_goyal 5/30/2023 #2

我稍微修改了你的代码来测试我的假设。

def rotate(nums, k):
    temp = nums[0:k+1]
    del nums[0:k+1]
    nums.extend(temp)

nums= [-1, -100, 3, 99]
k = 2
expected = [3, 99, -1, -100]
rotate(nums, k)
print("One:", nums, expected)


nums= [1,2,3,4,5,6,7,8]
k = 4
expected = [5,6,7,8,1,2,3,4]
rotate(nums, k)

print("Two:", nums, expected)

我假设您正在尝试从中间旋转列表。当列表的长度为奇数时,列表的中点会有所不同,在这种情况下,您只有一个中间点,因此您使用 [:k+1] 正确引用中间点。

如果一个列表的元素数量为偶数,则有两个中间点,例如 list =[1,2,3,4,5,6,7,8],没有一个中间点,只有两个中间点(4 和 5)。现在,问题来了,要考虑哪一个进行轮换,在你的例子中,你想考虑第一个,因此 [0:k] 有效。注意 - [:k+1] 将取第二个中间点。

解决方案是检查列表的长度是奇数还是偶数,并相应地应用切片。我希望这应该有效——

def rotate(nums, k):
    if len(nums)%2 == 1:
        temp = nums[0:k+1]
        del nums[0:k+1]
    else:
        temp = nums[0:k]
        del nums[0:k]
    
    nums.extend(temp)
0赞 Nicola Landro 5/30/2023 #3

因此,您对旋转第一个测试的实现没有通过,因为您正在推回前三个元素,而是希望将最后两个数字推送到列表顶部,因此:[0:k+1]

def rotate(nums, k):
  return nums[-k:] + nums[0:-k]

这样,您必须记住重新分配 .如果你想制作有副作用的方法,记得把方法放在方法的末尾,作为典型的 Python 约定。nums = rotate(nums, k)_

评论

0赞 Jamal 5/31/2023
顺便说一句,这个问题来自 leetcode.com/problems/rotate-array/......它期望向右旋转,而我向左旋转。