In regards to Python 2.7.12 (disclaimer: I understand Python2 is being phased out to Python3, but the course I'm taking started us here, perhaps to understand older code bases):
I have a list of integers whom I'd like to swap each with their neighboring value. So far, this works great for lists that are even in the number of integers they contain, however when the list length is odd, it's not so easy to simply swap each value, as the number of integers is uneven.
Giving the following code example, how can I swap all values other than the final value in the list?
arr = [1, 2, 3, 4, 5]
def swapListPairs(arr):
for idx, val in enumerate(arr):
if len(arr) % 2 == 0:
arr[idx], arr[val] = arr[val], arr[idx] # traditional swap using evaluation order
else:
arr[0], arr[1] = arr[1], arr[0] # this line is not the solution but where I know I need some conditions to swap all list values other than len(arr)-1, but am not sure how to do this?
return arr
print swapListPairs(arr)
Bonus Points to the ultimate Pythonic Master: How can this code be modified to also swap strings? Right now, I can only use this function using integers and am very curious how I can make this work for both int
and str
objects?
Thank you so greatly for any insight or suggestions to point me in the right direction! Everyone's help at times here has been invaluable and I thank you for reading and for your help!
Here's a shorter, probably faster way based on slice assignment:
def swap_adjacent_elements(l):
end = len(l) - len(l) % 2
l[:end:2], l[1:end:2] = l[1:end:2], l[:end:2]
The slice assignment selects the elements of l
at all even indices (l[:end:2]
) or all odd indices (l[1:end:2]
) up to and excluding index end
, then uses the same kind of swapping technique you're already using to swap the slices.
end = len(l) - len(l) % 2
selects the index at which to stop. We set end
to the closest even number less than or equal to len(l)
by subtracting len(l) % 2
, the remainder when len(l)
is divided by 2.
Alternatively, we could have done end = len(l) & ~1
, using bitwise operations. That would construct an integer to use as a mask (~1
), with a 0 in the 1 bit and 1s everywhere else, then apply the mask (with &
) to set the 1 bit of len(l)
to 0 to produce end
.
This is easier to do without enumerate
. Note that it never, ever makes decisions based on the contents of arr
; that is what makes it work on anything, not just a pre-sorted list of integers starting from 1.
for i in range(len(arr)//2):
a = 2*i
b = a+1
if b < len(arr):
arr[a], arr[b] = arr[b], arr[a]
Exercise for you: is the if
actually necessary? Why or why not?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With