Skip to main content

How to Compare Keys of Different Types in Python

In Python 3, strong typing rules prevent direct comparison between different data types. While Python 2 allowed you to compare an integer to a string (e.g., 1 < "a"), Python 3 raises a TypeError: '<' not supported between instances of 'int' and 'str'.

This behavior protects developers from logical errors, but it presents a challenge when sorting lists with mixed data types or organizing dictionaries with heterogeneous keys. This guide explains how to safely compare and sort mixed-type keys using type conversion and custom key functions.

Understanding the TypeError

Python 3 does not define a default ordering between different types. If you attempt to sort a list containing both integers and strings, or check if an integer key is greater than a string key, the operation fails.

# A list containing integers and strings
mixed_data = [10, 'apple', 5, 'banana']

try:
# ⛔️ Incorrect: Direct sorting fails in Python 3
sorted_data = sorted(mixed_data)
print(sorted_data)
except TypeError as e:
print(f"Error: {e}")

Output:

Error: '<' not supported between instances of 'str' and 'int'
note

Why does this happen? Python cannot logically determine if the number 5 is "smaller" than the word "apple". To resolve this, you must provide a rule (a key) that tells Python how to compare them.

Method 1: String Conversion (Simple Sort)

The simplest way to compare mixed types is to convert everything to a string temporarily during the comparison. This uses the lexicographical (dictionary) order.

Using key=str

The sorted() function and list.sort() method accept a key argument. By passing str, Python converts every item to a string before comparing.

mixed_data = [10, 'apple', 2, 'banana', 100]

# ✅ Correct: Sort based on string representation
sorted_data = sorted(mixed_data, key=str)

print(f"Original: {mixed_data}")
print(f"Sorted: {sorted_data}")

Output:

Original: [10, 'apple', 2, 'banana', 100]
Sorted: [10, 100, 2, 'apple', 'banana']
warning

Lexicographical Pitfall: Notice that 10 comes before 2 in the output above. In string comparison, character "1" comes before character "2". If you need numeric sorting for numbers, this method is insufficient.

Method 2: Tuple Grouping (Type-Aware Sort)

If you want to sort items such that all Integers come first (sorted numerically), followed by all Strings (sorted alphabetically), you can use a tuple key.

Python compares tuples element-by-element. We can create a key that returns: (type_name, value).

  1. Type Name: Groups items by type (e.g., "int" comes before "str").
  2. Value: Sorts the actual items within their type groups.
mixed_data = [10, 'apple', 2, 'banana', 100]

# ✅ Correct: Sort by type name first, then by value
# We use str(x) for the second element to ensure the second elements
# are comparable even if types differ in edge cases, strictly speaking
# the type separation usually prevents direct comparison of the second element across types.
def type_sort_key(item):
return (type(item).__name__, item)

# Sort
sorted_data = sorted(mixed_data, key=type_sort_key)

print(f"Sorted: {sorted_data}")

Output:

Sorted: [2, 10, 100, 'apple', 'banana']

Explanation:

  • Integers are converted to keys like ('int', 2), ('int', 10).
  • Strings are converted to keys like ('str', 'apple').
  • Since 'int' comes before 'str' alphabetically, all numbers appear before words.

Method 3: Safe Numeric Conversion

Sometimes keys are of different types (string and int) but represent the same concept (numbers). For example, a dictionary might contain 1 (int) and "5" (string). You might want to compare them numerically.

You can write a custom function that attempts to convert everything to a float, and falls back to string comparison if that fails.

mixed_numbers = [10, "2", 5, "1.5", "apple"]

def safe_numeric_key(item):
try:
# Try to treat it as a number
return (0, float(item))
except (ValueError, TypeError):
# Fallback: treat as a string, put it after numbers (1)
return (1, str(item))

# ✅ Correct: "2" and "1.5" are treated as numbers
sorted_nums = sorted(mixed_numbers, key=safe_numeric_key)

print(f"Sorted: {sorted_nums}")

Output:

Sorted: ['1.5', '2', 5, 10, 'apple']
note

This strategy uses tuple sorting again. The first element (0 or 1) ensures all convertable numbers appear before non-number strings.

Conclusion

To compare keys of different types in Python:

  1. Use key=str if you just need a quick, crash-free sort and don't care about numeric order (e.g., 10 before 2).
  2. Use key=lambda x: (type(x).__name__, x) if you want to group items by type (e.g., all numbers first, then all strings).
  3. Use a try-except wrapper if you need to interpret strings as numbers dynamically.