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

huangapple go评论52阅读模式
英文:

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

问题

切片操作似乎不一致。在某些情况下,切片包括第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]

我正在处理的整个问题可以在这里找到。

英文:

The slice operation does not seem consistent. In some cases slice includes the kth value and sometimes it doesn’t.

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()

The first test will fail and the second will pass when I do nums[:k+1].
the nums array for the failing test: [99, -1, -100, 3]

When I use nums[0:k] the first one passes and the second does not.
the nums array for the failing test: [4, 5, 6, 7, 1, 2, 3]

The whole question I am working on can be found here

答案1

得分: 0

你缺少了一个额外的索引。由于你停在 i+1,如果 k = 2 的话,你将切割三个元素 --> (0, 1, 2,除了3)。

在你的第一个情况中,temp = [-1, -100, 3],而 num 将会是 [99, -1, -100, 3]。

英文:

You are missing an additional index. Since you are stopping at i+1, you will slice three elements if you have k = 2 --> (0, 1, 2, except the 3).

In your first case temp = [-1, -100, 3] and the num will be [99, -1, -100, 3]

答案2

得分: 0

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

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]来引用中点。

对于具有偶数元素的列表,存在两个中点,例如列表=[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)
英文:

I modified your code a little bit to test my hypothesis.

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)

I assume you are trying to rotate the list from the middle. The mid-point of the list is different when the length of the list is an odd number in which case you have a single middle point, thus you refer the middle point using [:k+1] correctly.

In case of a list with even number of elements there are two middle points, example a list=[1,2,3,4,5,6,7,8], there is no single middle point but two of them (4 and 5). Now, the question comes which one to consider for rotation, in your case, you want to consider the first one and thus [0:k] works. Note- [:k+1] will take the second middle point.

The solution would be to check if the list has an odd or even length and apply slicing accordingly. I hope this should work-

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)

答案3

得分: 0

根据你的旋转实现,第一个测试未通过,因为你将前三个元素 [0:k+1] 放回列表,而实际上你想要将最后两个数字放在列表的顶部,所以应该这样做:

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

这种方式下,你需要记得重新赋值 nums = rotate(nums, k)。如果你想创建具有副作用的方法,请记得按照典型的Python约定在方法末尾加上 _

英文:

Accordingly your implementation of rotate the first test does not pass because you are pushing back the first three elements [0:k+1] instead you want to push the last two numbers in the top of the list so:

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

In this way you must remember to re-assign nums = rotate(nums, k). If you want to make methods with side effects, remember to put _ at the end of the methods as a typical Python convention.

huangapple
  • 本文由 发表于 2023年5月30日 06:32:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/76360650.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定