1
>> find_sub_anagram_in_wordlist('apple', ['ppl','al','app','apple'])

['ppl']

Why does the loop not add the other sub-anagrams?

Here is my code:

anagramList = []

def find_sub_anagram_in_wordlist(str, str_list):

    global anagramList
    anagramList.clear()
    list1 = list(str)
    list1.sort()
    for word in str_list:
        shouldAdd = True
        listi = list(word)
        listi.sort()
        for j in listi:
            if j in list1:
                list1.remove(j)
            else:
                shouldAdd = False
        if shouldAdd == True:
            anagramList.append(word)
    return anagramList
4
  • What do you actually want to achieve from this piece of code ? Commented Nov 13, 2015 at 17:20
  • The second argument is a list of strings which are to be checked whether or not they are sub-anagrams of the first argument. I want the code to check each element of the list in the second argument and add it to a separate list if it is a sub-anagram of the first argument, then at the end i want to return the list of sub-anagrams. Commented Nov 13, 2015 at 17:23
  • For clarity, please edit your code to show the desired output. Commented Nov 13, 2015 at 17:28
  • list object has no attribute clear. Can you show some code that actually works? Commented Nov 13, 2015 at 17:29

2 Answers 2

1

I think it will help to simplify what you're doing. In particular, separate the test for subanagramness functionally from the procedure for filtering the candidates. This would be my approach:

def is_sub_anagram( word, candidate ):
    word = list( word )
    for letter in candidate:
        try:
            word.remove( letter )
        except ValueError:
            return False
    return True


def filter_sub_anagrams( word, candidates ):
    return [ x for x in candidates if is_sub_anagram( word, x ) ]


print( filter_sub_anagrams( 'apple', [ 'ppl', 'al', 'app', 'apple', 'aapl' ] ) )

The output is:

['ppl', 'al', 'app', 'apple']

Note that 'aapl' is not and should not be included in the output.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you very much for your help, I appreciate it a lot!
@RNar Are my thoughts yours? Are your thoughts mine? omg, WHICH ONE OF US IS REAL?!
1

This line:

if j in list1:
    list1.remove(j)

is your problem. Think about the first iteration of for word in str_list where word == 'ppl

going through the following code with that in mind:

    for j in listi: #for every char in word, 'p', 'p', 'l'
        if j in list1: 'True for all three
            list1.remove(j) 'removes all three letters
        else:
            shouldAdd = False

this leaves you with list1 == ['a','e']. Your next iteration for word gives you word == 'al'. If we go through the above code again, you'll see that since there is no longer 'l' in list1, shouldAdd == False. Also, since a was in it, it now isn't and list1 == ['e']. You can see where this is going.

Using your code, you can fix this by moving list1 = list(str) to inside of your for word in str_list: loop so that it reinitializes the list every time. I am going to try to find a more pythonic way of doing the function and post it when I can.

EDIT:

Here is my way of doing this:

>>> def is_sub_anagram(s, sub):
    s = list(s)
    try:
        for c in sub: s.remove(c)
    except:
         return False
    return True
>>> def find_sub_anagram_in_wordlist(s, str_list):
    return list(filter(lambda x: is_sub_anagram(s,x), str_list))

>>> find_sub_anagram_in_wordlist('apple',['app','ppl','ae','le'])
['app', 'ppl', 'ae', 'le']

>>> find_sub_anagram_in_wordlist('apple',['app','ppl','ae','le','lle'])
['app', 'ppl', 'ae', 'le']

1 Comment

Thank you very much for your help, I appreciate it a lot!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.