Count unique element in a list [duplicate] - python

This question already has answers here:
Get unique values from a list in python [duplicate]
(30 answers)
Closed 2 years ago.
My question is to ask user input a world at a time and see how many unique world the user know (duplicate word wont count)
e.g.
Word: Chat
Word: Chien
Word: Chat
Word: Escargot
Word:
You know 3 unique word(s)!
below is what I have now:
count = 0
listword = []
word = input("Word: ")
while word != "":
for i in listword:
if i != word:
listword.append(word)
count += 1
word = input("Word: ")
print("You know "+count+"unique word(s)!")
however the output is like this:
Word: hello
Word: hi
Word: hat
Word:
You know 0 unique word(s)!
How can I adjust my code and why is count still =0?

The problem is that listword is initially empty, and nothing ever gets added unless the entered word doesn't match a word already in listword. What you really want to do is to add the word if it isn't found in listword.
You could do that with a list, but a set would be more efficient:
listword = set()
word = input("Word: ")
while word.strip() != "":
if word not in listword:
listword.add(word)
word = input("Word: ")
print("You know", len(listword), "unique word(s)!")

I would suggest using collections.Counter. This provides a simple an pythonic way to calculate total counts and is provided in the standard lib.
You could use it like this:
from collections import Counter
total_counts = Counter()
word = input("Word: ")
while word:
total_counts.update([word])
word = input("Word: ")
print("You know {:d} unique word(s)!".format(len(total_counts)))

Editing your code you can just do:
listword = []
word = input("Word: ")
while word: # empty strings are equal to false as a boolean, and anything in them is equal to true
if word not in listword:
listword.append(word)
word = input("Word: ")
print("You know ",len(listword),"unique word(s)!")
Although I would look into a more pythonic way of doing this if I were you.

Since at the start you declare an empty list:
listword = []
And only append items to it inside this loop:
for i in listword:
You'll never enter this loop, because the list will always be empty, thus you'll never cycle through count += 1.
So you should add another check to see if list is empty:
while word != "":
if len(listword) == 0:
listword.append(word)
count+=1
for i in listword:
if i != word:
#...

This code is same as yours with slight modification.
count = 0
listword = []
word = input("Word: ")
while word != "":
found= False
for i in listword:
if i == word:
found= True
if not found:
listword.append(word)
word = input("Word: ")
print("You know "+str(len(listword))+" unique word(s)!")

Related

Python: Same word twice in a list

I'm trying to write a program that stops if the same word is given twice. This code almost does the job, but it stops only if the duplicate words are given sequentially. Thanks for your help.
list = []
double = None
while True:
word = input("word: ")
lista.append(word)
if douple == word:
print(f"You gave {len(list)} words")
break
double = word
You need to check if the word is already in the list
seen = []
while True:
word = input("word: ")
if word in seen:
print(f"You gave {len(seen)} words")
break
seen.append(word)
If you just want to tell duplicates, and don't need to keep the order, you can use a set instead; this will be more efficient for a large number of words:
seen = set()
while True:
word = input("word: ")
if word in seen:
print(f"You gave {len(seen)} words")
break
seen.add(word)
Finally, in sufficiently recent Python (at least 3.6 or 3.7, depending on how you take things), you can do both by using a dictionary; this is both efficient and keeps the order in which the words were entered:
seen = {}
while True:
word = input("word: ")
if word in seen:
print(f"You gave {len(seen)} words")
break
seen[word] = None
Change your code to what is given below:
words_list = []
while True:
word = input("Word: ")
if word not in words_list: #Checks if the word is in the list. If it exists in list, it would return False
words_list.append(word)
else:
print(f"You gave {len(words_list)} words")
break
I have changed a few things:
Don't use list as a variable name as it is a keyword in Python.
Check for duplicate words using not in before you append it to the list. If word exists in the list, the loop would break.
This should do the work. You can always comment down if you need clarification or if the code dosen't work.

I don't understand this KeyError?

I'm doing this challenge where i am tasked at coding up a game of hangman - where I am supposed to reduce the range of words in a set.The rules of the game states that you get 8 tries too guess otherwise you'd lose.If the user were to key in the same letter more than once a message would pop up stating that he's already done so - I've used sets as a way to handle this part of the game. Below is my code:
word_list = ["python", "java", "kotlin", "javascript"]
word = random.choice(word_list)
word_set = set(word)
hidden = []
for i in word:
hidden.append("-")
# print(hidden)
print("H A N G M A N")
count = 0
while(count < 8):
print()
print("".join(hidden))
guess = input("Input a letter: ")
if guess in word:
if guess not in word_set:
print("No improvements")
count += 1
else:
for i in range(len(word)):
if word[i] == guess:
print(word_set)
word_set.remove(word[i])
hidden[i] = word[i]
if word_set == set():
print()
print(word)
print("You guessed the word!")
print("You survived!")
else:
print("No such letter in the word")
count += 1
print("You are hanged!")
The main problem I face is an error telling me that 'a' and only 'a' in particular is a key error which goes like this: Traceback (most recent call last):
File "/Users/laipinhoong/Desktop/learnpython.py/learning.py", line 29, in <module>
word_set.remove(word[i])
KeyError: 'a'
The problem appears when the chosen word has the same letter more once. In that case, since you iterate over all the letters in word (for i in range(len(word))) you will try to remove this word few times from the set word_set (as much as this letter appears in the word) but word_set will have this letter only once since set is unique collection. So in the second attempt to delete a from javascript or java, word_set.remove(word[i]) will fail cause the set will not contain this letter anymore.
In order to prevent the error, try to use:
word_set.discard(word[i]) instead. In that case, the letter will be removed if exists and if not, no exception will be raised.
You try to remove the same letter multiple times because you iterate the word - iterate its set of letters instead. You could also precalculate the positions of each letter in your word into a dictionary and use that to "fill in the gaps" like so:
word = "javascript"
seen = set() # letters that were guessed get added here
letters = set(word) # these are the letters to be guessed
hidden = ["_" for _ in word] # the output
positions = {l:[] for l in letters } # a dictionary letter => positions list
for idx,l in enumerate(word): # add positions of each letter into the list
positions[l].append(idx)
print("H A N G M A N")
count = 0
while count < 8:
print()
print("".join(hidden))
# allow only 1-letter guesses
guess = input("Input a letter: ").strip()[0]
# if in seen it is a repeat, skip over the remainder of the code
if guess in seen:
print("Tried that one already.")
continue
# found a letter inside your word
if guess in positions:
# update the output list to contain this letter
for pos in positions.get(guess):
hidden[pos]=guess
# remove the letter from the positions list
del positions[guess]
else: # wrong guess
count += 1
print("No improvements: ", 8-count, "guesses left.")
# remember the seen letter
seen.add(guess)
# if the positions dictionary got cleared, we have won and found all letters
if not positions:
print(word)
print("You guessed the word!")
print("You survived!")
break
# else we are dead
if count==8:
print("You are hanged!")
Output:
__________
Input a letter:
j_________
Input a letter:
ja_a______
Input a letter:
java______
Input a letter:
javas_____
Input a letter:
javasc____
Input a letter:
javascr___
Input a letter:
javascri__
Input a letter:
javascrip_
# on bad inputs:
No improvements: 7 guesses left.
# on win
javascript
You guessed the word!
You survived!
# on loose
You are hanged!
Your key error is going to happen every time you pick a letter that is repeated in the word. When you do word_set.remove(word[i]) inside a for i in range(len(word)): loop and the word has the same letter at multiple is, this key error will occur when it hits the second i corresponding to that letter in the word. This will make more sense to you if you step through your code in python tutor.
You need to understand what your code does:
When you remove a character from word_set.remove(word[i]). This removes it but on 2nd iteration it doesn't find the character thus it throws the key error because it cannot find the key which is already removed.
Try adding an if condition like in this code to check if key exists before removal practically bypass if it doesnt exists and save you from keyerror
import random
word_list = ["python", "java", "kotlin", "javascript"]
word = random.choice(word_list)
print(word)
word_set = set(word)
hidden = []
for i in word:
hidden.append("-")
#print(hidden)
print("H A N G M A N")
count = 0
while(count < 8):
print()
print("".join(hidden))
guess = input("Input a letter: ")
if guess in word:
if guess not in word_set:
print("No improvements")
count += 1
else:
for i in range(len(word)):
if word[i] == guess:
if word in word_set:
word_set.remove(word[i])
hidden[i] = word[i]
if word_set == set(hidden):
print()
print(word)
print("You guessed the word!")
print("You survived!")
else:
print("No such letter in the word")
count += 1
print("You are hanged!")
Set.remove() throws a KeyError if the item you are removing is not part of the set.
In your case, it's caused by the word_set and word not having the same letters.
E.g. If word = java, then word_set = ( j, a, v)
And since you are looping over word instead of word_set, your code will attempt to remove the letter 'a' twice from word_set, which will result in a keyError

Grok learning- "How many words"

I'm doing a question on grok learning, it asks for this:
You are learning a new language, and are having a competition to see how many unique words you know in it to test your vocabulary learning.
Write a program where you can enter one word at a time, and be told how many unique words you have entered. You should not count duplicates. The program should stop asking for more words when you enter a blank line.
For example:
Word: Chat
Word: Chien
Word: Chat
Word: Escargot
Word:
You know 3 unique word(s)!
​and
Word: Katze
Word: Hund
Word: Maus
Word: Papagei
Word: Schlange
Word:
You know 5 unique word(s)!
and
Word: Salam
Word:
You know 1 unique word(s)!
I cannot get it to work when there are multiple duplicates, here is my code:
word = input("Word: ")
l = []
l.append(word)
words = 1
while word != "":
if word in l:
word = input("Word: ")
else:
words = 1 + words
word = input("Word: ")
print("You know " + str(words) , "unique word(s)!" )
Using a set this problem can be solved easily:
l = set()
while True:
new_word = input("Word:")
if new_word=="":
break
l.add(new_word)
print("You know " + str(len(l)) , "unique word(s)!" )
This is a good example for the power of the Python standard library. Usually if you have a problem there already is a good solution in it.
There is also a way where you do not necessarily have to use the set() function. But it is still best if you learn about the set() function anyway.
Here's the code that doesn't need a set() function, but still works fine:
words = []
word = input('Word: ')
while word != '':
if word not in words:
words.append(word)
word = input('Word: ')
print('You know', len(words), 'unique word(s)!')

Python Palindrome Help: Count palindromes in a sentence

I have created a program in python that basically tells the user to enter a word and tells them if it's a palindrome or not.
My program:
def palindrome(word):
return word == word[::-1]
word = input("Enter a word: ")
word2 = word.lower()
if word2 == "":
print("You failed to input a word")
elif palindrome(word2) == True:
print(word2,"is a palindrome!")
else:
print(word2,"is not a palindrome!")
I need help modifying my program so that it allows the user to enter a sentence and counts the number of words in the sentence that are palindromes. When I execute the program I would want it to output the palindromes in the sentence.
I've been struggling with this for days and I can't seem to figure out where to start. Help would be much appreciated. Also, I need to MODIFY my program above, not make a completely different program.
You need to split the string into words then check if each word is a palindrome using a list comp, the length of the list will also give you the count:
def palindrome(word):
return word == word[::-1]
# split sentence into words and filter out the non palindromes
sentence = [w for w in input("Enter a sentence: ").split() if palindrome(w)]
print(" There are {} palindromes in your sentence\n.".format(len(sentence)))
# print each palindrome from our list
for pal in sentence:
print("{} is a palindrome".format(pal))
If you want to mimic your own code, keep a count as you iterate over the list of words increasing the count if we have a palindrome:
sentence = input("Enter a sentence: ").split()
count = 0
for w in sentence:
if palindrome(w):
count += 1
print("{} is a palindrome.")
else:
print("{} is not a palindrome.")
print(" There are {} palindromes in your sentence\n.".format(count))
To catch single non-letters:
def palindrome(word):
if len(word) > 1:
return word == word[::-1]
return word.isalpha()

Finding unique entries, using a list. Python

I am using grok learning and I can't seem to get passed this problem. You need to make a program program where you can enter one word at a time, and be told how many unique words you have entered. You should not count duplicates. The program should stop asking for more words when you enter a blank line.
This is my current code:
words = []
word = input("Word: ")
while word != '':
words.append(word)
word = input("Word: ")
print('You know', len(words), 'unique word(s)!')
It counts the amount of words you enter but I can't figure out how to make it check it the word is unique. Here are the desired outputs:
Word: Chat
Word: Chien
Word: Chat
Word: Escargot
Word:
You know 3 unique word(s)!
Here is another:
Word: Katze
Word: Hund
Word: Maus
Word: Papagei
Word: Schlange
Word:
You know 5 unique word(s)!
>>> words = ['Chat', 'Chien', 'Chat', 'Escargot']
>>> set(words)
set(['Chien', 'Escargot', 'Chat'])
>>> "You know " + str(len(set(words))) + " unique word(s)!"
'You know 3 unique word(s)!'
Use a set if you do not want to store duplicates.
words = set() #initialize a set
word = input("Word: ")
while word != '':
words.append(word)
word = input("Word: ")
print('You know', len(words), 'unique word(s)!')
If you want to store all the elements irrespective of duplicates, use a list
If you want to find unique elements inside a list, do this:
myset = set(words) #Now, myset has unique elements
print('You know', len(myset), 'unique word(s)!')
Based on what you should have learnt by that point in the course, you can use an if statement to check if the word you're looking at is already in the words list, and only add it if it is not already in the list:
words = []
word = input("Word: ")
while word != '':
if word not in words:
words.append(word)
word = input("Word: ")
print('You know', len(words), 'unique word(s)!')
You'll learn more about sets (which are a more efficient way to solve this question) later in the course.

Categories

Resources