Python
sorting
lists
algorithms
data manipulation

Sort 2 lists in Python based on the ratio of individual corresponding elements or based on a third list

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

When two or more Python lists represent aligned rows of data, the most important rule is to sort them together, not separately. If you sort each list independently, you destroy the relationship between corresponding elements. The safe pattern is to combine aligned values, sort once with a clear key, and then unpack the result if you still need separate lists afterward.

Sort by the Ratio of Corresponding Elements

Suppose you have two lists a and b, and you want the ordering to depend on a[i] / b[i]. Zip the lists into row pairs first, then sort by a ratio key.

python
1a = [10, 30, 8, 21]
2b = [2, 5, 4, 7]
3
4rows = list(zip(a, b))
5rows_sorted = sorted(rows, key=lambda pair: pair[0] / pair[1])
6
7a_sorted, b_sorted = map(list, zip(*rows_sorted))
8print(a_sorted)
9print(b_sorted)

That keeps row alignment intact because Python sorts whole pairs instead of separate values.

The same idea works for descending order:

python
rows_sorted_desc = sorted(rows, key=lambda pair: pair[0] / pair[1], reverse=True)
print(rows_sorted_desc)

Handle Division by Zero Explicitly

Ratio-based sorting needs a policy for b[i] == 0. Do not leave that undefined.

python
1def ratio_key(x, y):
2    if y == 0:
3        return float("inf")  # puts zero denominators at the end in ascending order
4    return x / y
5
6rows_sorted = sorted(rows, key=lambda pair: ratio_key(pair[0], pair[1]))
7print(rows_sorted)

Other valid policies include:

  • reject the row with an exception
  • filter zero-denominator rows before sorting
  • treat them as lowest priority instead of highest

The right choice depends on the business meaning of the data.

Sort Two Lists Based on a Third List

If the ordering is determined by a separate ranking list, zip all three aligned sequences and sort on that third value.

python
1names = ["A", "B", "C", "D"]
2values = [100, 200, 300, 400]
3priority = [0.7, 0.1, 0.5, 0.3]
4
5rows = list(zip(names, values, priority))
6rows_sorted = sorted(rows, key=lambda row: row[2])
7
8names_s, values_s, priority_s = map(list, zip(*rows_sorted))
9print(names_s)
10print(values_s)
11print(priority_s)

This is the general solution whenever several lists form one logical table.

Index-Based Sorting Is Another Good Pattern

Sometimes you do not want to zip and unzip the data. In that case, compute sorted indices and apply them to every list.

python
1a = [10, 30, 8, 21]
2b = [2, 5, 4, 7]
3
4idx = sorted(range(len(a)), key=lambda i: a[i] / b[i])
5
6a_sorted = [a[i] for i in idx]
7b_sorted = [b[i] for i in idx]
8print(a_sorted)
9print(b_sorted)

This is useful when you have many aligned lists and want one shared ordering vector.

Prefer Tabular Structures When the Data Is Really Tabular

If you already have multiple related columns, a table abstraction is often easier to maintain than manually managing several lists.

With pandas, the same operation becomes clearer:

python
1import pandas as pd
2
3df = pd.DataFrame({
4    "a": [10, 30, 8, 21],
5    "b": [2, 5, 4, 7],
6    "priority": [0.7, 0.1, 0.5, 0.3],
7})
8
9df["ratio"] = df["a"] / df["b"]
10print(df.sort_values("ratio"))
11print(df.sort_values("priority"))

For anything beyond a few small lists, this is usually more readable than repeated zip logic.

Common Pitfalls

  • Sorting aligned lists independently and breaking row relationships.
  • Ignoring division-by-zero behavior in ratio sorting.
  • Forgetting that string values such as "10" and "2" sort lexically unless converted.
  • Skipping length validation when lists are supposed to be aligned.
  • Using separate sort keys for separate lists when one shared ordering is required.

Summary

  • Combine aligned lists before sorting so row relationships stay intact.
  • For ratio sorting, sort zipped pairs using a ratio key.
  • Define zero-denominator behavior explicitly.
  • When ordering depends on a third list, zip all aligned sequences and sort by that field.
  • If the data is really tabular, a DataFrame is often cleaner than several parallel lists.

Course illustration
Course illustration

All Rights Reserved.