Python lists not working properly - python

import random
words = ["Football" , "Happy" ,"Sad", "Love", "Human"]
for word in words:
word = random.choice(words)
print(word)
words.remove(word)
Why does the above code only print out 3 words instead of all 5? Am I trying to achieve printing the words from wordsin a random order in an incorrect way?

You can't modify a list (by adding or removing elements) while iterating over it, the behaviour is undefined. Here's a possible alternative for what you're doing that doesn't have that problem:
random.shuffle(words)
for word in words:
print(word)

This is because you are not looping correctly. Try this:
import random
words = ["Football" , "Happy" ,"Sad", "Love", "Human"]
while words:
word = random.choice(words)
print(word)
words.remove(word)
You need to make sure that the list words is not empty because you cannot modify an array whilst iterating over it.

People have mostly explained why you're not getting the behavior you want, but just to throw an alternate solution into the mix using a different idiom:
import random
words = ["Football" , "Happy" ,"Sad", "Love", "Human"]
random.shuffle(words)
while words:
print(words.pop())

you should not modify a list while iterating over it try
for _ in range(len(words)):
word = random.choice(words)
words.remove(word)
print word

To explicitly state blogbeards suggestion,
>>>import random
>>>random.shuffle(words)
>>>print(*words)

Related

Word frequency counter in file

I am working on an assignment and I have hit a wall. The assignment requires me to count the frequency of words in a text file. I got my code to count the words and put them into a dictionary but cannot put words together if they have different cases. For example I need the output to show {'a':16...} but it outputs this instead {'A':2...'a':14}. Here is my code. Any help would be much appreciated.
file=open("phrases.txt","r")
wordCount={}
for word in file.read().split():
if word not in wordcount:
wordcount[word]=1
else:
wordcount[word]+=1
print(wordcount)
You can use an inbuilt function called Counter for this as an alternative to looping through the list.
example :
from collections import Counter
file = open("phrases.txt","r")
data = file.read().lower().split() # added lower() will convert everything to lower case
wordcount = dict(Counter(data))
print(wordcount)
Seems like in the question your saying there is a uppercase and lowercase issue, so why not:
file=open("phrases.txt","r")
wordCount={}
for word in file.read().split():
if word.lower() not in wordcount:
wordcount[word.lower()]=1
else:
wordcount[word.lower()]+=1
print(wordcount)
Or:
file=open("phrases.txt","r")
wordCount={}.fromkeys([i.lower() for i in file.read().split()],1)
for word in file.read().split():
wordcount[word.lower()]+=1
print(wordcount)
lower all the words when comparing.
for word.lower() in file.read().split():
You can convert the words to lowercase, and then count them. So, your code changes to something like this.
file=open("phrases.txt","r")
wordCount={}
for word in file.read().split():
newWord = word.lower()
if newWord not in wordcount:
wordcount[newWord]=1
else:
wordcount[newWord]+=1
print(wordcount)
Basically, you will be storing in the dict, where keys are the lower case versions of each word.
Do note, that you will lose "data", if you are doing operations which are case sensitive.

When I replace one list with another list, something goes wrong

I'm doing an assignment in which I have to make a Hangman game. I just started from scratch using my very basic knowledge. A lot of things might be more efficient in a different way, but I enjoy figuring out my own solutions. So here is my code. The idea is that I want to switch from one list to another list. But when I do the rest of the code fails, where it worked before.
import random
alphabet = list('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
allwords = []
with open('google-10000-english-usa-no-swears-long.txt') as inputfile:
for line in inputfile:
allwords.append(line.strip().split(','))
words = ['apple', 'banana', 'coconut']
word = random.choice(words)
guessesleft = 8
sentence1 = ('You have %d guesses!\n') % guessesleft
length = len(word)
uslist = ['_'] * length
hangword = list(word)
The problem is as follows: In the code, currently 'words' is used and that works. However, now instead of using 'words' as a list of words, I want to use the textfile and 'allwords' as a list of words (so I change word=random.choice(words) in word=random.choice(allwords). It does select a random word from the file, but after that it goes wrong. Every word only produces on '_' instead of 1 for every letter in the randomly chosen word. Are my lists different? How do I fix this?
Is there any reason you are using the split function?
allwords.append(line.strip().split(','))
The split() function returns a list of items separated by the delimiter so even in a string without the delimiter, the function will return a list
"helloworld".split(",") # returns ["helloworld"]
If you only want the first element after the split, you can use:
allwords.append(line.strip().split(',')[0])

Python: making a wordcounter that excludes words less than three letters long

I'm very new to python and I've been trying to make a wordcounter that excludes words less than three letters long. Right now my basic counter looks like this:
wordcount = len(raw_input("Paste your document here: ").split())
print wordcount
This returns the word count but I can't figure out how to make it exclude words with three letters or less. Every time I try something new, I get an iteration error. I've been scouring the internet for some ideas on how to make python recognize how long certain words are, but I haven't had much luck. Any help would be appreciated.
Code -
wordcount = raw_input("Paste your document here: ").split()
wordcount = [word for word in wordcount if len(word) >= 3]
You're on the right path. You just split on the input, then using a list comprehension to only select words with len >= 3:
words = raw_input("Paste your document here: ").split()
newwords = [word for word in words if len(word) >= 3
wordcount = len(newwords)

Printing plurals from a list

Pretty noobie, but I'm trying to write a function that prints all the plural words in a list of words
So output would be:
>>> printPlurals(['computer', 'computers', 'science,', 'sciences'])
computers
sciences
and this is what I have so far but I'm not getting any output. Any help would be great. ty.
def printPlurals(list1):
plural = 's'
for letter in list1:
if letter[:-1] == 's':
return list1
You're really close, but you're mixing a few things up. For starters, you don't need to have the plural variable. You're not using it anyway. Secondly, from a naming standpoint, it doesn't matter that you've named the variable letter as you have, but it implies that maybe you think you're looping through letters. Since you're actually looping through the members of the list list1, you're considering a word at each iteration. Finally, you don't want to return the list. Instead, I think you want to print the word that has been confirmed to end in s. Try the following. Good luck!
def print_plurals(word_list):
for word in word_list:
if word[-1] == 's':
print word
In case you're interested in doing something a little more interesting (or "Pythonic", arguably), you could form the list of plurals through a list comprehension as follows:
my_list = ['computer', 'computers', 'science', 'sciences']
plural_list = [word for word in my_list if word[-1]=='s']
Have you considered using the Python inflect library?
p = inflect.engine()
words = ['computer', 'computers', 'science', 'sciences']
plurals = (word for word in words if p.singular_noun(word))
print "\n".join(plurals)
It might seem strange to check if p.singular_noun since you asked for the plural values, but it makes sense when you consider that p.singular_noun(word) returns False when word is already singular. So you can use it to filter the words that are not singular.
A one liner way to do this is
def printPlurals(list1):
print [word for word in list1 if word[-1]=='s']
Your main issue is that letter[:-1] will return everything up to the last letter. For just the last letter use [-1]. You also were returning values and not printing. You can either just fix those two issues, or use the one liner in this answer.
So your code fixed is:
def printPlurals(list1):
plural = 's' #you don't need this line, as you hard coded 's' below
for letter in list1:
if letter[-1] == 's':
print list1

python - remove string from words in an array

#!/usr/bin/python
#this looks for words in dictionary that begin with 'in' and the suffix is a real word
wordlist = [line.strip() for line in open('/usr/share/dict/words')]
newlist = []
for word in wordlist:
if word.startswith("in"):
newlist.append(word)
for word in newlist:
word = word.split('in')
print newlist
how would I get the program to remove the string "in" from all the words that it starts with? right now it does not work
#!/usr/bin/env python
# Look for all words beginning with 'in'
# such that the rest of the word is also
# a valid word.
# load the dictionary:
with open('/usr/share/dict/word') as inf:
allWords = set(word.strip() for word in inf) # one word per line
using 'with' ensures the file is always properly closed;
I make allWords a set; this makes searching it an O(1) operation
then we can do
# get the remainder of all words beginning with 'in'
inWords = [word[2:] for word in allWords if word.startswith("in")]
# filter to get just those which are valid words
inWords = [word for word in inWords if word in allWords]
or run it into a single statement, like
inWords = [word for word in (word[2:] for word in allWords if word.startswith("in")) if word in allWords]
Doing it the second way also lets us use a generator for the inside loop, reducing memory requirements.
split() returns a list of the segments obtained by splitting. Furthermore,
word = word.split('in')
doesn't modify your list, it just modifies the variable being iterated.
Try replacing your second loop with this:
for i in range(len(newlist)):
word = newlist[i].split('in', 1)
newlist[i] = word[1]
It's difficult to tell from your question what you want in newlist if you just want words that start with "in" but with "in" removed then you can use a slice:
newlist = [word[2:] for word in wordlist if word.startswith('in')]
If you want words that start with "in" are still in wordlist once they've had "in" removed (is that what you meant by "real" in your comment?) then you need something a little different:
newlist = [word for word in wordlist if word.startswith('in') and word[2:] in wordlist
Note that in Python we use a list, not an "array".
Suppose that wordlist is the list of words. Following code should do the trick:
for i in range(len(wordlist)):
if wordlist[i].startswith("in"):
wordlist[i] = wordlist[i][2:]
It is better to use while loop if the number of words in the list is quite big.

Categories