为什么切片和排序无法将列表反向到位?

时间:2019-07-25 17:02:33

标签: python

我正在对LeetCodeN(https://leetcode.com/problems/next-permutation/)进行NextPermutation问题。问题需要我就地解决。问题出在这里(来源:LeetCode):

“实施下一个排列,将字典中的数字重新排列成数字的下一个更大的排列。

如果无法进行这种排列,则必须将其重新排列为最低可能的顺序(即,以升序排列)。

替换必须就位并且仅使用恒定的额外内存。

这里有一些例子。输入在左侧栏中,其对应的输出在右侧栏中。

1,2,3→1,3,2 3,2,1→1,2,3 1,1,5→1,5,1 “ [结束]

尝试使用nums = nums [::-1]和nums = sorted(nums)都失败了测试用例nums = [3,2,1],因为数组似乎是未排序的。在这些分配之后,我还打印了nums,stdout为[1,2,3],这是正确的。此错误没有意义,因为代码的最后一行nums [inverse_pt + 1:] = sorted(nums [inverse_pt + 1:])已按预期修改了我的列表。最后,我尝试了nums.sort(),它可以就地排序,并且可以解决问题。

我已经读过reverse listslicing上的线程。

def nextPermutation(self, nums: List[int]) -> None:
    """
    Do not return anything, modify nums in-place instead.
    """
    if not nums or len(nums) == 1:
        return 
    # find inverse pt
    # O(1) because only 1 variable declared
    inverse_pt = len(nums) - 2
    while inverse_pt >= 0 and nums[inverse_pt+1] <= nums[inverse_pt]:
        inverse_pt -= 1

    if inverse_pt < 0:
        nums = sorted(nums)
        print(nums) # [1,2,3]
        return

    # find a smallest elem that's bigger than inverse_pt
    for i in range(len(nums)-1, inverse_pt, -1):
        if nums[i] > nums[inverse_pt]:
            nums[i], nums[inverse_pt] = nums[inverse_pt], nums[i]
            break

    # sort what's after new elem at inverse_pt
    nums[inverse_pt+1:] = sorted(nums[inverse_pt+1:])

1 个答案:

答案 0 :(得分:0)

它们之所以不能归类,是因为它们的设计方式并非如此。

切片总是会创建一个新列表,该列表以某种顺序包含原始列表中的某些元素子集。

sorted()方法不会对列表进行排序,它会返回列表的排序版本

sorted(iterable, /, *, key=None, reverse=False)
    Return a new list containing all items from the iterable in ascending order.
           ^^^^^^^^^^

reversed()方法相同。

如果要就地对列表进行排序,只需执行lst.sort()

sort(self, /, *, key=None, reverse=False)
    Stable sort *IN PLACE*.

通常,这是python设计哲学的一部分。通常,方法会 改变其对象返回该对象的新的变异版本,而不对其进行更改。有几个值得注意的例外,主要是list.pop()(出于数据科学的原因很重要,可以看作是两个连续操作的简写),但是切片和sorted()(和reversed() )遵循这种范例。