-1

I'm new to python and am trying to make a function that swaps multiple values in a list at once.

def swap(deck: List[int], start1: int, end1: int, start2: int, end2: int) -> None: 

    start1 = start1 % len(deck)
    start2 = start2 % len(deck)


    end1 = end1 % len(deck)
    end2 = end2 % len(deck)

    if start1 < start2:
        deck[start1: end1], deck[start2: end2] = deck[start2: end2], deck[start1: end1]
    else:
        deck[start2: end2], deck[start1: end1] = deck[start1: end1], deck[start2: end2]

when deck = [0,1,2,3,4,5,6,7,8,9,10] swap(deck, -3, 11, 0, 2) should mutate the deck to be [8,9,2,3,4,5,6,7,0,1,10], but I get this instead [2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 10]

I have also tried it with the temp variable method

    temp = deck[start1: start1]

    deck[start1: start1] = deck[start2: end2]

    deck[start2: end2] = temp

but I get the same result... An explanation of why this is happening and how I can fix it is greatly appreciated.

lenik
  • 23,228
  • 4
  • 34
  • 43
JPJW
  • 1
  • 1
  • Think carefully about what `end1` will be after doing `end1 = end1 % len(deck)`, and therefore what slice will be taken. Then consider a simpler interface for the code. Think - the slices that will be swapped, should be the same length, right? Therefore, how many parameters are actually needed in order to explain what to swap? – Karl Knechtel Feb 27 '23 at 09:04

2 Answers2

0

Because your two ranges are not the same size, the deck list changes size after the first assignment, so the range where the temp content is assigned does not correspond to the original positions.

for example:

deck = [0,1,2,3,4,5,6,7,8,9,10]
temp = deck[0:2]         # temp is [0,1]  
deck[0:2] = deck[-3:11]  # deck is now [8, 9, 10, 2, 3, 4, 5, 6, 7, 8, 9, 10]
deck[-3:11] = temp       # [8,9] is replaced by [0,1] 
                         # because -3 is now at position 9 instead of  8

one way to fix this (assuming your ranges never overlap) is to form a concatenation of the 5 slices of the deck: [before range1]+[range2]+[between ranges]+[range1]+[after range2], or more specifically, assign the total subrange with the concatenation of the 3 middle parts

deck[start1:end2] = deck[start2:end2] + deck[end1:start2] + deck[start1:end1]
Alain T.
  • 40,517
  • 4
  • 31
  • 51
0

Basically, what you want to do is:

deck = deck[s2:e2] + deck[e1:s2] + deck[s1:e1]

Don't try to use two variables before and after the equal sign =.

lenik
  • 23,228
  • 4
  • 34
  • 43