Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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.

share|improve this question
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. – kampu 19 hours ago
I know. Thank you. I just wanted to show the results of print asap, without saving original lines of input (y variable). – Reloader 17 hours ago

2 Answers

up vote 4 down vote accepted

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']
share|improve this answer
append seems more suitable here. – Elazar 19 hours ago
3  
@Elazar: No, y is a list of words. The OP wanted one list of words, not a list of lists. – Martijn Pieters 19 hours ago
OK you are right. – Elazar 19 hours ago
   
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 19 hours ago
@Reloader: Are printing words at the end of the loop, or are you printing y in the loop? – Martijn Pieters 19 hours ago
show 3 more comments
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)
share|improve this answer
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? – whatyouhide 19 hours ago
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? – Reloader 17 hours ago
+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 – Sylvain Leroux 17 hours ago
@Reloader added version with no imports – jamylak 17 hours ago
Why I can't toggle both answers as correct? :( – Reloader 16 hours ago
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.