sabs6488
sabs6488

Reputation: 467

Anagram check in Python

I am trying to write a program that will compare two lists of words and check the words to see if they are anagrams.

eg.,

input : ['cinema','host','aab','train'], ['iceman', 'shot', 'bab', 'rain']

I am using the below code:

#!/usr/bin/env python
anagram_dict = {}

def anagram_solver(first_words,second_words):
    for word in first_words:
         first_word = list(word)
         second_word = list(second_words[first_words.index(word)])
         first_copy = first_word
         second_copy = second-word
         if len(first_word) != len(second_word):
              anagram_dict[first_words.index(word)] = 0
         else:
              for char in first_word:
                  second_word = second_copy
                  if char in second_word:
                       first_copy.remove(char)
                       second_copy.remove(char)
                  else:
                      pass
              if len(first_copy) == len(second_copy):
                  print first_copy
                  print second_copy
                  anagram_dict[first_words.index(word)] = 1
              else:
                  anagram_dict[first_words.index(word)] = 0
    for k,v in anagram_dict.items():
    print "%d : %d" %(k,v)

if __name__ == "__main__":
     anagram_solver(['cinema','host','aab','train'],['iceman','shot','bab','rain'])

When I execute this script, in the for loop for char in first_word: the loop is skipped, by one list item. for example, if it is processing the list ['c','i','n','e','m','a'] it only processes 'c','n','m' and ignores the other items. If I remove the list.remove(), then it doesn't skip the items.

One can execute this script to better understand, what I am trying to explain here.

Just wondering why is this behavior and how to overcome this ?

Upvotes: 1

Views: 1625

Answers (6)

Marco Bonelli
Marco Bonelli

Reputation: 69276

You can simply sort the words and check if they are equal:

def anagram_solver(first_words, second_words):
    result = []
    for i in xrange(len(first_words)):
        a = list(first_words[i])
        b = list(second_words[i])
        a.sort()
        b.sort()
        
        result.append(a == b)
    return result

Example:

>>> a = ['cinema','host','aab','train']
>>> b = ['iceman', 'shot', 'bab', 'rain']
>>> anagram_solver(a, b)

[True, True, False, False]

Upvotes: 4

Innomight
Innomight

Reputation: 556

def anagram(string_one, string_two):
    string_one = string_one.replace(' ', '').lower()
    string_two = string_two.replace(' ', '').lower()
    string_list_one = []
    string_list_two = []
    for letters in string_one:
        string_list_one.append(letters)

    for letters_t in string_two:
        string_list_two.append(letters_t)

    string_list_one.sort()
    string_list_two.sort()

    if(string_list_one == string_list_two):
        return True
    else:
        return False

Upvotes: 0

KashtheCoder
KashtheCoder

Reputation: 1

There are two ways to do this. One is pretty easy and other one is a bit complicated but is Optimal. First Method

def anagram1(s1,s2):
# We need to get rid of the empty spaces and
# lower case the string

s1 = s1.replace(' ', '').lower()
s2 = s2.replace(' ', '').lower()

# Now we will return boolean for sorted match.
return sorted(s1) == sorted(s2)

The next Method is bit longer:

def anagram2(s1, s2):
# We will remove spaces and will lower case the string
s1 = s1.replace(' ', '').lower()
s2 = s2.replace(' ', '').lower()

# We will do the edge case to check if both strings have same number of letters
if len(s1) != len(s2):
    return False

# will creat an empty dictionary.
count = {}

for letter in s1:
    if letter in count:
        # We are assigning value 1 for every letter in s1
        count[letter] += 1
    # if it is the start of loop u just want to assign one into it.
    else:
        count[letter] = 1

for s2 we will do the opposite.

for letter in s2:
    if letter in count:
        # We are making every value of the letters from 1 to zero
        count[letter] -= 1
    else:
        count[letter] = 1

for k in count:
    if count[k] != 0:
        return False

# other wise just return true
return True

Upvotes: 0

Padraic Cunningham
Padraic Cunningham

Reputation: 180391

You can use enumerate with sorted:

[sorted(a[ind]) == sorted(ele) for ind, ele in enumerate(b)]

Upvotes: 1

Sylvain Leroux
Sylvain Leroux

Reputation: 51990

To answer to your question according to its title: "Anagram check in Python"

You can do that in one three lines:

first_words = ['cinema','host','aab','train']
second_words = ['iceman', 'shot', 'bab', 'rain']

print [sorted(a) == sorted(b) for (a,b) in zip(first_words,second_words)]

Producing:

[True, True, False, False]

Upvotes: 1

Neal Miller
Neal Miller

Reputation: 196

Python handles lists by reference, so when you set first_copy = first_word, you're actually just making first_copy and first_word point to the same list. You can overcome this behavior (actually copy the list) using

first_copy = first_word[:]
second_copy = second_word[:]

Upvotes: 4

Related Questions