-1

I need to call various different functions that i have already created in order to achieve the question below. I am really unsure how to programme this in order to achieve it. The question is..

Find two word anagrams in word list( str, str list ), where the input parameters should be a string and a list of strings. The output should be a list of all strings made up of two words separated by a space, such that both of these words are in str list and the combination of the two words is an anagram of str.

The output i expect is:

wordlist = ('and','band','nor,'born')
find_two_word_anagrams_in_wordlist( "brandon", wordlist )
[’and born’, ’band nor’]

How to achieve this is:

  • Initialise a list two word anagrams to the empty list, [].
  • Call find partial anagrams in word list to get a list of all the partial anagrams of str that can be found in the word list.
  • Then, do a loop that runs over all these partial anagrams. For each partial anagram part anag do the following:
  • Remove the letters of part anag from the input string, str, to get a string, rem that is the remaining letters after taking away the partial anagram;
  • Call find anagrams in word list on rem (and the input word list) to get a list of anagrams of the remaining letters;
  • For each anagram rem anag of the remaining letters, form the string part anag + " " + rem anag and add it to the list two word anagrams.
  • At this point the list two word anagrams should have all the two word anagrams in it, so return that list from your function.

Code i have already created is:

def find_partial_anagrams_in_word_list(str1,str_list):
    partial_anagrams = []
    for word in str_list:
         if (partial_anagram(word, str1)):
             partial_anagrams.append(word)
    print(partial_anagrams)

def remove_letters(str1,str2):
    str2_list = list(str2)
    for char in str2:
        if char in str1:
             str2_list.remove(char)
    return "".join(str2_list)

def find_anagrams_in_word_list(str1,str_list):
    anagrams = []
    for word in str_list:
            if (anagram(str1,word)):
                anagrams.append(word)
                print(word)

Any step by step help or input would be appreciated.

alfiej12
  • 371
  • 3
  • 4
  • 15

2 Answers2

0

You have two choices, you can look at anagrams in combinations of two different words, or you can look at anagrams in all two by two combinations.

The choice is yours, here I have implemented both

from itertools import combinations, combinations_with_replacement

def ana2(s,wl):
    rl = []
    for w1, w2 in combinations(wl,2):
        w = w1+w2
        if len(w) != len(s): continue
        if sorted(w) == sorted(s): rl.append((w1, w2)
    return rl

def ana2wr(s,wl):
    rl = []
    for w1, w2 in combinations_with_replacement(wl,2):
        w = w1+w2
        if len(w) != len(s): continue
        if sorted(w) == sorted(s): rl.append((w1, w2))
    return rl

and here it is some testing

wl = ('and','band','nor','born')
s1 = 'brandon'
s2 = 'naddan

print ana2(s1,wl)
print ana2(s2,wl)

print ana2wr(s1,wl)
print ana2wr(s2,wl)

that produces the following output

[('and', 'born'), ('band', 'nor')]
[]
[('and', 'born'), ('band', 'nor')]
[('and', 'and')]
gboffi
  • 22,939
  • 8
  • 54
  • 85
  • 1
    your parameter is `wl` but you use `wordlist`. In short: `ana = lambda s,wl,cnt=2: filter(lambda a, s=sorted(s):sorted(''.join(a))==s, combinations(wl, cnt))` – Daniel Nov 22 '14 at 16:47
  • Thank you for finding my mistake. In effect I'm not sure that my answer is OK for the OP, that asked for help re his/her way of finding the anagram... – gboffi Nov 22 '14 at 16:56
  • @gboffi thank you for your answer but in my question i have said how it needed to be done, I'm just struggling doing it. – alfiej12 Nov 22 '14 at 20:40
  • @alfiej12 I've already doubted of the relevance of my answer re your Q in my answer to Daniel. Now I'm pretty sure! Do you prefer that I delete my answer altogether? – gboffi Nov 22 '14 at 20:53
0

You wrote

I need to call various different functions that i have already created in order to achieve the question below

def find_2_word_anagram(word, wordlist)            
    # Initialise a list two word anagrams to the empty list, [].
    analist = []

    # Call find partial anagrams in word list to get a list of all the
    # partial anagrams of str that can be found in the word list.
    candidates = find_partial_anagrams_in_word_list(word,wordlist)


    # Then, do a loop that runs over all these partial anagrams
    for candidate in candidates:
        # Remove the letters of part anag from the input string, str, to
        # get a string, rem that is the remaining letters after taking
        # away the partial anagram
        remaining = remove_letter(candidate,words)
        # Call find anagrams in word list on rem (and the input word list)
        # to get a list of anagrams of the remaining letters;
        matches = find_anagrams_in_word_list(remaining, wordlist)
        for other in matches:
            analist.append(" ".join(candidate,other))

    return analist

Note that

  1. you have still to write the inner functions following your specifications
  2. when you write a function that returns, e.g., a list of words you MUST RETURN A LIST OF WORDS, and in particular I mean that it isn't enough that you print the matches from your function
  3. to find an anagram, the idiom sorted(w1)==sorted(w2) is all you need, but the story with finding a partial anagram is more complex...
  4. I took the liberty of inlining one of your functions, the one that computes the remainder.
  5. When you strip the comments, that are your verbatim your specs, you have very few lines of code.

Post Scriptum

Have a thorough look at Daniel's comment to my previous answer, there's a lot in it...

gboffi
  • 22,939
  • 8
  • 54
  • 85
  • This is getting there thankyou! although it says invalid syntax on the 'for' on 'c for c in word if c not in candidate' – alfiej12 Nov 22 '14 at 23:16
  • I have to say three things (1) You shouldn't have a syntax error on that, I've tested it and it is syntactically correct. (2) it doesn't matter because the code is semantically wrong (the code removes ***all the occurrences*** in `word` of any character that is also present in `candidate`). (3) You have to write your `remove_letters`. I've edited my answer to reflect these points. – gboffi Nov 23 '14 at 00:16
  • Another issue, you'll see that `partial_anagram` and `remove_letters` are _almost_ the same function. This imply that you can compute the candidate and the remainder at once, and return both from a single function. – gboffi Nov 23 '14 at 00:23