1

I'm currently learning Python and I need to write a program which determines the word which appears the most times in a poem. Problem which is troubling me is about parsing a lines of a poem into a SINGLE list containing words of the poem. When I solve it i will have no trouble determining the word which appears the most times.

I can access the lines of the poem by calling input() repeatedly, and the last line contains the three characters ###.

So, i wrote:

while True:
 y = input()
 if y == "###":
 break
 y = y.lower()
 y = y.split()

and for input:

Here is a line like sparkling wine
Line up now behind the cow
###

got result:

['here', 'is', 'a', 'line', 'like', 'sparkling', 'wine']
['line', 'up', 'now', 'behind', 'the', 'cow']

If i try to call y[0], i get:

here
line

How can I concatenate two lists within same variable, or how can I assign every line to different variable?

Any hint is appreciated. Thanks.

jamylak
135k30 gold badges238 silver badges240 bronze badges
asked Jun 9, 2013 at 8:57
2
  • 2
    In general, reusing a variable name like this (y is variously a string, a lowercased string, and finally a list.) is a bad idea, as it makes your code more confusing. It would be better to write eg inputline = input(), if inputline == "###":, lowercased = inputline.lower(), words = lowercased.split(). If you don't do this kind of thing, you may often find that a variable contains something quite different than you thought when you scanned the code. Commented Jun 9, 2013 at 9:15
  • I know. Thank you. I just wanted to show the results of print asap, without saving original lines of input (y variable). Commented Jun 9, 2013 at 11:10

2 Answers 2

5

You need to add y to an existing list, using list.extend():

words = []
while True:
 y = input()
 if y == "###":
 break
 y = y.lower()
 y = y.split()
 words.extend(y)

Now words is a list containing all the words of the lines your user entered.

Demo:

>>> words = []
>>> while True:
... y = input()
... if y == "###":
... break
... y = y.lower()
... y = y.split()
... words.extend(y)
... 
Here is a line like sparkling wine
Line up now behind the cow
###
>>> print(words)
['here', 'is', 'a', 'line', 'like', 'sparkling', 'wine', 'line', 'up', 'now', 'behind', 'the', 'cow']
answered Jun 9, 2013 at 8:58
Sign up to request clarification or add additional context in comments.

6 Comments

append seems more suitable here.
@Elazar: No, y is a list of words. The OP wanted one list of words, not a list of lists.
Program output with extend: ['here', 'is', 'a', 'line', 'like', 'sparkling', 'wine'] ['here', 'is', 'a', 'line', 'like', 'sparkling', 'wine', 'line', 'up', 'now', 'behind', 'the', 'cow'] I need one list.
@Reloader: Are printing words at the end of the loop, or are you printing y in the loop?
@Reloader: You are printing words inside the loop. It shows you the list has grown for the second line. Move the print statement outside the loop. Look at the example I gave you.
|
3
words = []
while True:
 y = input()
 if y == "###":
 break
 words.extend(y.lower().split())
from collections import Counter
Counter(words).most_common(1)

This whole code can be compressed into the following one liner:

Counter(y.lower() for x in iter(input, '###') for y in x.split()).most_common(1)

eg.

>>> sys.stdin = StringIO.StringIO("""Here is a line like sparkling wine
Line up now behind the cow
###""")
>>> Counter(y.lower() for x in iter(input, '###') for y in x.split()).most_common(1)
[('line', 2)]

As per request, without any imports

c = {} # stores counts
for line in iter(input, '###'):
 for word in line.lower().split():
 c[word] = c.get(word, 0) + 1 # gets count of word or 0 if doesn't exist
print(max(c, key=c.get)) # gets max key of c, based on val (count)

To not have to make a second pass over the dictionary to find the max word, keep track of it as you go along:

c = {} # stores counts
max_word = None
for line in iter(input, '###'):
 for word in line.lower().split():
 c[word] = c.get(word, 0) + 1 # gets count of word or 0 if doesn't exist
 if max_word is None:
 max_word = word
 else:
 max_word = max(max_word, word, key=c.get) # max based on count 
print(max_word)
answered Jun 9, 2013 at 9:01

5 Comments

IMHO this code goes a little bit against the Zen of Python. I mean, I find it classy in some sort of sense, but it's quite cryptic. What do you think?
This code prints out correct answer, but I shouldn't use outside function to solve this problem. Only str.lower() and str.split() methods. Can it be done without importing the Counter function?
+1 for the collections.Countersolution. One might consider this most pythonic by the virtue it is almost the exact same example provided in the official documentation for Counter
@Reloader added version with no imports
@Reloader Accept the answer you found most helpful to yourself ;)

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.