'Sort the odd numbers in the list

How can I sort ascending the odd numbers in a list of integers, but leaving the even numbers in their original places?

Example:

sortArray([5, 3, 2, 8, 1, 4]) == [1, 3, 2, 8, 5, 4]

My code:

def sort_array(source_array):     
    odd_numbers = [n for n in source_array if n%2!=0]
    odd_numbers = sorted(odd_numbers)

How do I switch the indices of the odd numbers in source_array with the ones in odd_numbers?



Solution 1:[1]

Looks like you're almost there - you can make your sorted odd numbers an iterable and re-build your source list with either the original even number or the next sorted odd number, eg:

>>> data = [5, 3, 2, 8, 1, 4]
>>> odds = iter(sorted(el for el in data if el % 2))
>>> [next(odds) if el % 2 else el for el in data]
[1, 3, 2, 8, 5, 4]

Solution 2:[2]

More lines but also more readable

a = [5, 3, 2, 8, 1, 4]
b = sorted([item for item in a if item%2 != 0])
odd_int = 0
for i in range(len(a)):
    if a[i] %2 != 0:
        a[i] = b[odd_int]
        odd_int += 1

Solution 3:[3]

If you're open to using numpy, you can get the indices of odd numbers using np.where, sort the odd numbers and update the array using the previously obtained indices assigning to the sorted array of odd numbers:

import numpy as np

a = np.array([5, 3, 2, 8, 1, 4])
ind = np.where(a%2)                 # get indices of odd items
a[ind] = np.sort(a[ind])            # update items at indices using sorted array
print(a)
# array([1, 3, 2, 8, 5, 4])

Solution 4:[4]

def sort_array(source_array):
    odd_numbers = sorted([n for n in source_array if n%2!=0])
    c = 0
    res = []
    for i in source_array:
        if i %2!=0:
            res.append(odd_numbers[c])
            c += 1
        else:
            res.append(i)
    return res  

Solution 5:[5]

def sort_array(source_array):
    sorted_array = [i for i in source_array if i % 2 != 0]
    sorted_array.sort()
    for index, item in enumerate(source_array):
        if item % 2 == 0:
            sorted_array.insert(index, item)
    return sorted_array

Solution 6:[6]

def sort_array(arr):
  odds = sorted((x for x in arr if x%2 != 0), reverse=True)
  return [x if x%2==0 else odds.pop() for x in arr]

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Jon Clements
Solution 2
Solution 3
Solution 4 Rakesh
Solution 5 Pavel
Solution 6 user18609885