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 ;)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.