-1

In this program, I am trying to swap odd and even positions of the integers in a sequence of all positive integers. n is the size of the sequence and each integer in the sequence cannot be more than n. I have to take the value of n from the user.

note: If n (the size of the sequence) is odd, I will have to print -1.

Here's is my code:

def permu_size(n):
    
    lst = []
    
    if (n % 2 != 0):
        print(-1)
    else:
        for i in range(1, n+1):
            lst.append(i)
        for k in range(len(lst)):
            x = lst[2k]
            y = lst[2k+1]
            x, y = y, x
            print(x, y, end=" ")
            

n = int(input())
permu_size(n)

In my code, I am getting SyntaxError: invalid syntax (, line 11) in line 11. But I cannot figure out what is triggering this error.

Stack.A
  • 19
  • 4
  • 1
    I see another obvious problem. You loop over all of the valid index values in your list via the line `for k in range(len(lst)):`, but then you try to access an item in the list via `lst[2 * k]`. By the time you get to the end of your `for` loop, this expression is always going to throw an exception because you'll be attempting to read past the end of the list. Of course, the next line will be just as much of a problem. – CryptoFool Feb 19 '22 at 19:40
  • CryptoFool I have fixed it by changing it to: for k in range(len(lst)//2): Thanks for noting it – Stack.A Feb 19 '22 at 19:41
  • Does this answer your question? [Is there a standardized method to swap two variables in Python?](https://stackoverflow.com/q/14836228/6045800) – Tomerikoo Feb 20 '22 at 15:07

2 Answers2

2

2k isn't a valid expression in Python. Use 2 * k.

Note that you'll end up hitting an IndexError once 2*k >= n. Since you're multiplying the index by 2, you should divide the range by 2:

def permu_size(n):
    if n % 2:
        print(-1)
        return

    lst = list(range(1, n+1))
    for i in range(n // 2):
        lst[2*i], lst[2*i+1] = lst[2*i+1], lst[2*i]
    print(*lst)
10
2 1 4 3 6 5 8 7 10 9

You can generate the same result a bit more succinctly by simply taking two ranges and combining them in the appropriate order:

def permu_size(n):
    if n % 2:
        print(-1)
    else:
        print(*(i for t in zip(range(2, n+1, 2), range(1, n+1, 2)) for i in t))
Samwise
  • 68,105
  • 3
  • 30
  • 44
1

If you are going to always use numbers from 1 to n, this is essentially a math problem where you need to generate a sequence with inverted odd/even values: 2, 1, 4, 3, ...

n = 10
A = [ 1+i+(-1)**i for i in range(n) ]

print(A)
[2, 1, 4, 3, 6, 5, 8, 7, 10, 9]

If you want it to flip positions in an existing list, you can use slicing to swap between even and odd subsets of item positions:

A = [1,2,3,4,5,6,7,8,9,10]

A[::2],A[1::2] = A[1::2],A[::2]

print(A)
[2, 1, 4, 3, 6, 5, 8, 7, 10, 9]

You could also do it in a loop, striding by 2 to only get even indexes and invert the 2 items starting at the even positions:

for i in range(0,len(A),2):
    A[i:i+2] = reversed(A[i:i+2])

Using a list comprehension, you could pick the next or previous item depending on the index being even or odd:

A = [A[i+(-1)**i] for i in range(len(A))]

Or combine the values at odd/even positions using zip:

A = [n for oddEven in zip(A[1::2],A[::2]) for n in oddEven]
Alain T.
  • 40,517
  • 4
  • 31
  • 51