5 Best Ways to Check for Anagrams in Python

Rate this post

πŸ’‘ Problem Formulation: Determining whether two strings are anagrams is a common programming challenge. An anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once. For example, the input strings “listen” and “silent” should be identified as anagrams.

Method 1: Sorting and Comparing

This method involves sorting the characters in both strings and comparing the results. If the sorted versions of the strings are identical, they are anagrams. This basic approach is highly understandable and easy to implement in Python.

Here’s an example:

def is_anagram(str1, str2):
    return sorted(str1) == sorted(str2)

print(is_anagram("listen", "silent"))

The output of this code is:

True

In this snippet, the is_anagram() function sorts both input strings and compares them. It returns True if they are anagrams, suggesting that the character composition is identical.

Method 2: Using a Hash Table

A hash table (like a Python dictionary) can be used to count the occurrences of each character in both strings. If both strings have the same character counts for every character, they are anagrams. This approach is efficient for larger strings.

Here’s an example:

from collections import Counter

def is_anagram(str1, str2):
    return Counter(str1) == Counter(str2)

print(is_anagram("listen", "silent"))

The output of this code is:

True

Here, the is_anagram() function utilizes the Counter class from the collections module to create frequency maps for both strings and compares them.

Method 3: Increment and Decrement Counts

This strategy builds on using a hash table but instead of creating two maps, it increments character counts for one string and decrements for the other. If all counts are zero by the end, the strings are anagrams.

Here’s an example:

def is_anagram(str1, str2):
    if len(str1) != len(str2):
        return False
    
    count = {}
    for char in str1:
        count[char] = count.get(char, 0) + 1
    for char in str2:
        count[char] = count.get(char, 0) - 1
        if count[char] < 0:
            return False
    return all(value == 0 for value in count.values())

print(is_anagram("listen", "silent"))

The output of this code is:

True

The is_anagram() function iterates through the first string to increment character counts and through the second string to decrement them, finally verifying if all counts are zero.

Method 4: Prime Multiplication

Since prime multiplication is unique for a set of numbers, assigning a prime number to each letter and multiplying them together gives a unique product for each set of characters. Two anagrams will have the same product.

Here’s an example:

from functools import reduce
from operator import mul

def prime_char_map():
    # A dummy simplification where a=2, b=3, c=5, etc. Actual implementation should assign primes properly!
    return {chr(i + 97): i + 2 for i in range(26)}

def is_anagram(str1, str2):
    char_map = prime_char_map()
    product = lambda word: reduce(mul, (char_map[c] for c in word), 1)
    return product(str1) == product(str2)

print(is_anagram("listen", "silent"))

The output of this code is:

True

After mapping characters to primes, the is_anagram() function calculates the product for each string and compares them. The prime multiplication method guarantees that only true anagrams will have the same product.

Bonus One-Liner Method 5: Using the all() Function

For a concise solution, Python’s all() function can be used to check if all counted letters from one string are present in the other, considering their counts. It’s a compressed form of the hash table comparison.

Here’s an example:

from collections import Counter

is_anagram = lambda str1, str2: all(Counter(str1)[ch] == Counter(str2)[ch] for ch in str1)

print(is_anagram("listen", "silent"))

The output of this code is:

True

This one-liner uses a lambda function and the all() function to verify that the character counts for every character in the first string are equal to those in the second string.

Summary/Discussion

  • Method 1: Sorting and Comparing. Strengths: Simple and straightforward. Weaknesses: Not the most efficient for large strings due to sorting.
  • Method 2: Using a Hash Table. Strengths: Efficient for large datasets. Weaknesses: Requires additional space for the counters.
  • Method 3: Increment and Decrement Counts. Strengths: More space-efficient than two separate hash tables. Weaknesses: Slightly more complex logic than previous methods.
  • Method 4: Prime Multiplication. Strengths: Highly efficient and unique representation. Weaknesses: Assigning prime numbers can be complex and multiplication may cause overflow for long strings.
  • Bonus Method 5: Using the all() Function. Strengths: Extremely concise. Weaknesses: May be less readable and each lookup in the Counter can be inefficient.