5 Best Ways to Swap Consecutive Even Elements in Python

Rate this post
5 Best Ways to Swap Consecutive Even Elements in Python

πŸ’‘ Problem Formulation: In Python, swapping elements within a list is a common task. This article specifically addresses the question of how to swap consecutive even numbers in a list. For example, given the input list [1, 2, 4, 3, 6, 8], the desired output after swapping consecutive even numbers would be [1, 4, 2, 3, 8, 6].

Method 1: Using Loops

This method involves iterating over the list with a loop checking for consecutive even numbers and then swapping them. It is straightforward and easily comprehensible, yet manual indexing may increase the risk of errors.

Here’s an example:

def swap_consecutive_evens(lst):
    for i in range(0, len(lst) - 1, 2):
        if lst[i] % 2 == 0 and lst[i + 1] % 2 == 0:
            lst[i], lst[i + 1] = lst[i + 1], lst[i]
    return lst

print(swap_consecutive_evens([1, 2, 4, 3, 6, 8]))

Output:

[1, 4, 2, 3, 8, 6]

This snippet defines a function swap_consecutive_evens() which uses a for loop to go through the list two elements at a time, checking if both are even, and if so, swaps them using tuple unpacking. The altered list is then returned.

Method 2: List Comprehensions

Python’s list comprehensions simplify the process of creating lists. By combining list comprehensions with slicing, swapping elements can become a more concise operation.

Here’s an example:

def swap_consecutive_evens(lst):
    even_indices = [i for i in range(len(lst)) if lst[i] % 2 == 0]
    for i in range(0, len(even_indices) - 1, 2):
        lst[even_indices[i]], lst[even_indices[i + 1]] = lst[even_indices[i + 1]], lst[even_indices[i]]
    return lst

print(swap_consecutive_evens([1, 2, 4, 3, 6, 8]))

Output:

[1, 4, 2, 3, 8, 6]

This function utilizes a list comprehension to identify the indices of all even numbers. Subsequently, it loops over these indices in pairs and swaps the values at these positions. This method avoids unnecessary checks on odd numbers.

Method 3: Using the zip() Function

The zip() function can pair elements and aid in processing pairs concurrently. This can help in modifying only the even pairs of the list without much hassle.

Here’s an example:

def swap_consecutive_evens(lst):
    lst[1::2], lst[::2] = zip(*[(
        lst[i], lst[i+1])
        for i in range(0, len(lst) - 1, 2)
        if lst[i] % 2 == 0 and lst[i + 1] % 2 == 0
    ])
    return lst

print(swap_consecutive_evens([1, 2, 4, 3, 6, 8]))

Output:

[1, 4, 2, 3, 8, 6]

The swap_consecutive_evens() function above uses list comprehension to find and swap even pairs, then zip() combines them back into the proper order. Note this is slightly more complex and needs to be handled carefully when original list length is odd.

Method 4: NumPy Approach

For numerical operations, especially on large datasets, using NumPy can significantly speed up the process. Swapping elements with NumPy is straightforward due to advanced slicing and bulk operations.

Here’s an example:

import numpy as np

def swap_consecutive_evens(lst):
    arr = np.array(lst)
    even_mask = arr % 2 == 0
    even_values = arr[even_mask]
    even_values[1::2], even_values[::2] = even_values[::2], even_values[1::2]
    arr[even_mask] = even_values
    return arr.tolist()

print(swap_consecutive_evens([1, 2, 4, 3, 6, 8]))

Output:

[1, 4, 2, 3, 8, 6]

In this method, we convert the list to a NumPy array, use a boolean mask to isolate even values, and swap them with advanced slicing. This code is efficient and effective, particularly for numeric lists.

Bonus One-Liner Method 5: Functional Approach

Leveraging Python’s more functional aspects can lead to very concise and sometimes more readable code.

Here’s an example:

swap_consecutive_evens = lambda lst: [x if i % 2 or x % 2 or lst[i-1] % 2 else lst[i-1] for i, x in enumerate(lst)]

print(swap_consecutive_evens([1, 2, 4, 3, 6, 8]))

Output:

[1, 4, 2, 3, 8, 6]

This one-liner leverages a lambda function with a list comprehension and enumerate to swap consecutive even elements in a list. It’s a compact and neat solution, although it might sacrifice a bit of readability for brevity.

Summary/Discussion

  • Method 1: Loops. Simple to understand but requires manual index management.
  • Method 2: List Comprehensions with Slicing. More compact and focuses only on even numbers but still loop-based.
  • Method 3: Using zip(). Provides a more functional approach but can be complex and less straightforward.
  • Method 4: NumPy Approach. Adaptable and fast for large datasets but requires an external library.
  • Method 5: Functional One-Liner. Extremely concise but may be hard to read for those unfamiliar with functional programming.