Hi everyone i'm very new to python , only have been working with it for about a week, and I have the following question.I'm making a Lingo game in which you guess a needed word, but the first letter is always given when started

I have 3 lists in which i'm adding words seperated per letter so for example:

# neededword is the word you need to guess
neededwordlist=

#this is the raw input of the user for example now i entered :
rawlist =

# mask is the return of a string of a method which checks if any letters are matched and then puts a '*' on incorrect letters which i then add to a list.

i then convert them to sets to make it easier and that's worked pretty well .I've experimented for many hours and my problem is as follows, I can find the matching letter which are in the wrong order and print them, but I can't seem to find a way to print them when i have 2 of the same letters in the list for example:

word to guess : apples
raw input: aplpes
it will print out set[l]
but it won't check for the 2nd 'p' as it has already found there is a 'p' in both lists.

Is there any way to solve this or any other way to do this , any help is appreciated :)

## All 11 Replies Sets maybe be easier, but as you've found, they're wrong.

Consider the following -

``````>>> word = "fishcakes"
>>> list(word)
['f', 'i', 's', 'h', 'c', 'a', 'k', 'e', 's']
>>> set(word)
set(['a', 'c', 'e', 'f', 'i', 'h', 'k', 's'])
>>> set(word) == list(word)
False
>>> ''.join(set(word)) == word
False
>>> ''.join(list(word)) == word
True``````

Set elements are unique - as such, you can't have a set with two identical elements in.
The same is not true of lists

For these reasons, set is not the correct data structure to use. list is suitable, and if you want a feature complete version, define your own class for the word.

commented: Thanks so much for the explanation! +0

You can use the following

``````neededwordlist= ['a','p','p','l','e']
rawlist = ['a','l','p','p','e']

need, raw = list(neededwordlist), list(rawlist) # make copies
for i in range(min(len(need), len(raw))):
if need[i] == raw[i]:
need[i] = raw[i] = '!'
wrongposition = set(need) & set(raw)
print wrongposition

""" --> my output
set(['p', 'l'])
"""``````

The idea is that the letters in wrong positions are the letters which still belong to both lists after all the correct matches have been removed.

commented: simple and clear explanation thanks! +0

Thanks so very much for your support and explanation , so best to use a set if you don't want duplicates and list for if u do want duplicates. Didnt' expect a reply so fast + 1 for you guys :) and the community

Thanks a lot for your input but I have 1 more problem with the following , I implemented the code into the following :

``````def wrongletters(self,input):
neededword= self.neededWord
raw=input
neededwordlist = []; rawlist=[]

for nletter1 in neededword:#add letters into lists
neededwordlist.append(nletter1)

for rletter2 in raw:
rawlist += rletter2

need, raw = list(neededwordlist), list(rawlist) # make copies
for i in range(min(len(need), len(raw))):
if need[i] == raw[i]:#if same letters
need[i] = raw[i] = '!'
wrongposition = set(raw) & set(need)
#                    Wrongposition=list(wrongposition)#convert back to a list

print"".join(list(wrongposition))``````

and I call this method here :

``````def guessAWord(self):
attempt=5

check=Checks()
check.neededWord=self.words.getNextRandomWord()
input="      "

while attempt>0 and check.wordguessed==False :
attempt -=1
check.wrongletters(input)

return check.wordguessed``````

The problem now is that its returning me multiple strings
that are being printed for example my word to guess is banana so i start with b******:

b*****bonano
an
an
an
n

its returning me the wrong letters here i should only be getting back an 'a'

now if my word to guess is apples:

a*****seplas
apsel
apsel
asel
ase
ase
ae
a*pl*s

I have no idea whats going wrong now :( would love to here your input

Lines 16 to 20 should not be under the for loop. Watch the code indention.

Lines 16 to 20 should not be under the for loop. Watch the code indention.

Really appreciate the help ! outstanding

``````neededwordlist= ['a','p','p','l','e']
rawlist = ['a','l','p','p','e']

need, raw = list(neededwordlist), list(rawlist) # make copies
for i in range(min(len(need), len(raw))):
if need[i] == raw[i]:
need[i] = raw[i] = '!'
wrongposition = set(need) & set(raw)
print wrongposition

""" --> my output
set(['p', 'l'])
"""``````

Does this mean any list contents that match are a '!' and then u discard them ?
I would like to know what exactly the red colored text does, if i need it again in the future ,thanks in advance.

Add print statements to see what it does

``````neededwordlist= ['a','p','p','l','e']
rawlist = ['a','l','p','p','e']

need, raw = list(neededwordlist), list(rawlist) # make copies
for i in range(min(len(need), len(raw))):
if need[i] == raw[i]:
need[i] = raw[i] = '!'
print "i = ", i
print need
print raw
wrongposition = set(need) & set(raw)
print wrongposition
print wrongposition

""" my output -->
i =  0
['!', 'p', 'p', 'l', 'e']
['!', 'l', 'p', 'p', 'e']
i =  1
['!', 'p', 'p', 'l', 'e']
['!', 'l', 'p', 'p', 'e']
i =  2
['!', 'p', '!', 'l', 'e']
['!', 'l', '!', 'p', 'e']
i =  3
['!', 'p', '!', 'l', 'e']
['!', 'l', '!', 'p', 'e']
i =  4
['!', 'p', '!', 'l', '!']
['!', 'l', '!', 'p', '!']
set(['!', 'p', 'l'])
set(['p', 'l'])
"""``````

There are other ways to do it, for python gurus, like

``````A, B = (set(x) for x in zip(*((a,b) for (a,b) in zip(neededwordlist, rawlist) if a != b)))
wrongposition = A & B``````

I think set intersection is insufficient to give hints properly for misplaced letters. You should also know what you want to say if user inputs one letter in wrong place and there is such letter in two other places. List representation is not needed but we can use string directly for zip.

``````>>> needed = 'apple'
>>> guess = 'alxpe'
>>> indexes, a, b = zip(*((ind, char, charn) for ind, (char, charn) in enumerate(zip(*(needed, guess))) if char != charn))
>>> wrong = [(ind, c1, c2) for ind, c1, c2 in zip(indexes, a, b) if c2 in a]
>>> wrong
[(1, 'p', 'l'), (3, 'l', 'p')]
>>> set(a) & set(b)
set(['p', 'l'])
>>> guess = 'elppa'
>>> wrong = [(ind, c1, c2) for ind, c1, c2 in zip(indexes, a, b) if c2 in a]
>>> wrong
[(1, 'p', 'l'), (3, 'l', 'p')]
>>>``````

Time finished to update, so the previous second example was left scrambled. I did not re-evaluate the help variables:

``````>>> guess = 'elppa'
>>> indexes, a, b = zip(*((ind, char, charn) for ind, (char, charn) in enumerate(zip(*(needed, guess))) if char != charn))
>>> wrong = [(ind, c1, c2) for ind, c1, c2 in zip(indexes, a, b) if c2 in a]
>>> wrong
[(0, 'a', 'e'), (1, 'p', 'l'), (3, 'l', 'p'), (4, 'e', 'a')]
>>>``````

Disclaimer: I only know MasterMind, not Lingo.

``````def wrongletters(self,input):
neededword= self.neededWord
raw=input
neededwordlist = []; rawlist=[]

for nletter1 in neededword:#add letters into lists
neededwordlist.append(nletter1)

for rletter2 in raw:
rawlist += rletter2

need, raw = list(neededwordlist), list(rawlist) # make copies
for i in range(min(len(need), len(raw))):
if need[i] == raw[i]:#if same letters
need[i] = raw[i] = '!'
wrongposition = set(raw) & set(need)