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.

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']
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)

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

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.