简体   繁体   中英

Assigning python deque to list

The problem is to rotate a list by moving the numbers from the right, k times. eg [1,2,3,4,5,6,7] with k=3 will rotate the numbers from the right one at a time and move them to the top of the list so the output would be [5,6,7,1,2,3,4]. Rather than using the pop and insert operation in the list, I decided to use the dequue data type in python that supports adding to the left of the list in O(1). However, I am not quite sure how the conversion happens from dequeue to list. The second function works whereas the first doesn't. If you can explain why, it would be much appreciated.

from collections import deque

def rotateNums(nums, k):
  dq = deque(nums)
  for _ in range(0,k):
    num = dq.pop()
    dq.appendleft(num)
  nums = list(dq)

def rotateNums(nums, k):
  dq = deque(nums)
  for _ in range(0,k):
    num = dq.pop()
    dq.appendleft(num)
  nums[:] = list(dq)

nums = [1,2,3,4,5,6,7]
k = 3
print(f'nums before rotation: {nums}')
rotateNums(nums, k)
print(f'nums after rotation: {nums}')

Output from the first function is: nums after rotation: [1, 2, 3, 4, 5, 6, 7]

Output from the second function is: [5, 6, 7, 1, 2, 3, 4]

The issue is not in the conversation from deque to list, which you do correctly with nums[:] = list(dq) in both cases. It's with the line nums = list(dq) in the first function. This reassigns the name num to a different list object locally in the function. The subsequent replacement operation operates on a local object, not the list you passed in.

On a side note, you don't need to explicitly convert dq back to a list to assign it. It's already iterable, and a sequence, so you can do nums[:] = dq just fine.

This is happening due to scoping. In the first function, you are assigning the value of deque to nums with this code, nums = list(dq) . This tells python that this nums is a local variable to the function rotateNums . So it has no effect in the outside nums . Instead, if you did this:

def rotateNums(nums, k):
  dq = deque(nums)
  for _ in range(0,k):
    num = dq.pop()
    dq.appendleft(num)
  nums = list(dq)
  nums[:] = list(dq)
  return nums
nums = [1,2,3,4,5,6,7]
k = 3
print(f'nums before rotation: {nums}')
nums = rotateNums(nums, k)
print(f'nums after rotation: {nums}')

The output will be:

nums before rotation: [1, 2, 3, 4, 5, 6, 7]
nums after rotation: [5, 6, 7, 1, 2, 3, 4]

Whereas in the second one, by calling nums[:] = you are accessing and modifying the elements of nums , which is permitted and does not create a local variable nums .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM