counting how often the same word appears in a txt file...But my codeonly prints the last line entry

D

dgcosgrave

Hi Iam just starting out with python...My code below changes the txt file into a list and add them to an empty dictionary and print how often the word occurs, but it only seems to recognise and print the last entry of the txt file. Any help would be great.

tm =open('ask.txt', 'r')
dict = {}
for line in tm:
line = line.strip()
line = line.translate(None, '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~')
line = line.lower()
list = line.split(' ')
for word in list:
if word in dict:
count = dict[word]
count += 1
dict[word] = count
else:
dict[word] = 1
for word, count in dict.iteritems():
print word + ":" + str(count)
 
J

Jussi Piitulainen

Hi Iam just starting out with python...My code below changes the txt
file into a list and add them to an empty dictionary and print how
often the word occurs, but it only seems to recognise and print the
last entry of the txt file. Any help would be great.

tm =open('ask.txt', 'r')
dict = {}
for line in tm:
line = line.strip()
line = line.translate(None, '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~')
line = line.lower()
list = line.split(' ')
for word in list:
if word in dict:
count = dict[word]
count += 1
dict[word] = count
else:
dict[word] = 1
for word, count in dict.iteritems():
print word + ":" + str(count)

The "else" clause is mis-indented (rather, mis-unindented).

Python's "for" statement does have an optional "else" clause. That's
why you don't get a syntax error. The "else" clause is used after the
loop finishes normally. That's why it catches the last word.
 
S

Steven D'Aprano

Hi Iam just starting out with python...My code below changes the txt
file into a list and add them to an empty dictionary and print how often
the word occurs, but it only seems to recognise and print the last entry
of the txt file. Any help would be great.

tm =open('ask.txt', 'r')
dict = {}
for line in tm:
line = line.strip()
line = line.translate(None, '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~')
line = line.lower()
list = line.split(' ')

Note: you should use descriptive names. Since this is a list of WORDS, a
much better name would be "words" rather than list. Also, list is a built-
in function, and you may run into trouble when you accidentally re-use
that as a name. Same with using "dict" as you do.

Apart from that, so far so good. For each line, you generate a list of
words. But that's when it goes wrong, because you don't do anything with
the list of words! The next block of code is *outside* the for-loop, so
it only runs once the for-loop is done. So it only sees the last list of
words.
for word in list:

The problem here is that you lost the indentation. You need to indent the
"for word in list" (better: "for word in words") so that it starts level
with the line above it.
if word in dict:
count = dict[word]
count += 1
dict[word] = count

This bit is fine.
else:
dict[word] = 1

But this fails for the same reason! You have lost the indentation.

A little-known fact: Python for-loops take an "else" block too! It's a
badly named statement, but sometimes useful. You can write:


for value in values:
do_something_with(value)
if condition:
break # skip to the end of the for...else
else:
print "We never reached the break statement"

So by pure accident, you lined up the "else" statement with the for loop,
instead of what you needed:

for line in tm:
... blah blah blah
for word in words:
if word in word_counts: # better name than "dict"
... blah blah blah
else:
...

for word, count in dict.iteritems():
print word + ":" + str(count)

And this bit is okay too.


Good luck!
 
T

Thomas Bach

Hi,

just as a side-note

for word in list:
if word in dict:
count = dict[word]
count += 1
dict[word] = count
else:
dict[word] = 1

When you got the indentation and names right, you can restate this as

import collections
counter = collections.Counter(words)

in Python 2.7 or as

import collections
counter = collections.defaultdict(int)
for word in words:
counter[word] += 1

in Python 2.6

Regards,
Thomas.
 
D

dgcosgrave

Hi Iam just starting out with python...My code below changes the txt
file into a list and add them to an empty dictionary and print how
often the word occurs, but it only seems to recognise and print the
last entry of the txt file. Any help would be great.

tm =open('ask.txt', 'r')
dict = {}
for line in tm:
line = line.strip()
line = line.translate(None, '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~')
line = line.lower()
list = line.split(' ')
for word in list:
if word in dict:
count = dict[word]
count += 1
dict[word] = count

dict[word] = 1
for word, count in dict.iteritems():
print word + ":" + str(count)



The "else" clause is mis-indented (rather, mis-unindented).



Python's "for" statement does have an optional "else" clause. That's

why you don't get a syntax error. The "else" clause is used after the

loop finishes normally. That's why it catches the last word.

Thanks for quick reply Jussi...indentation fixed the problem :)
 
D

dgcosgrave

Hi Iam just starting out with python...My code below changes the txt
file into a list and add them to an empty dictionary and print how often
the word occurs, but it only seems to recognise and print the last entry
of the txt file. Any help would be great.

tm =open('ask.txt', 'r')
dict = {}
for line in tm:
line = line.strip()
line = line.translate(None, '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~')
line = line.lower()
list = line.split(' ')



Note: you should use descriptive names. Since this is a list of WORDS, a

much better name would be "words" rather than list. Also, list is a built-

in function, and you may run into trouble when you accidentally re-use

that as a name. Same with using "dict" as you do.



Apart from that, so far so good. For each line, you generate a list of

words. But that's when it goes wrong, because you don't do anything with

the list of words! The next block of code is *outside* the for-loop, so

it only runs once the for-loop is done. So it only sees the last list of

words.


for word in list:



The problem here is that you lost the indentation. You need to indent the

"for word in list" (better: "for word in words") so that it starts level

with the line above it.


if word in dict:
count = dict[word]
count += 1
dict[word] = count



This bit is fine.


dict[word] = 1



But this fails for the same reason! You have lost the indentation.



A little-known fact: Python for-loops take an "else" block too! It's a

badly named statement, but sometimes useful. You can write:





for value in values:

do_something_with(value)

if condition:

break # skip to the end of the for...else

else:

print "We never reached the break statement"



So by pure accident, you lined up the "else" statement with the for loop,

instead of what you needed:



for line in tm:

... blah blah blah

for word in words:

if word in word_counts: # better name than "dict"

... blah blah blah

else:

...




for word, count in dict.iteritems():
print word + ":" + str(count)



And this bit is okay too.





Good luck!

Thanks Steven appreciate great info for future coding. i have change names to be more decriptive and corrected the indentation... all works! cheers
 
D

dgcosgrave

Hi,



just as a side-note



for word in list:
if word in dict:
count = dict[word]
count += 1
dict[word] = count

dict[word] = 1



When you got the indentation and names right, you can restate this as



import collections

counter = collections.Counter(words)



in Python 2.7 or as



import collections

counter = collections.defaultdict(int)

for word in words:

counter[word] += 1



in Python 2.6



Regards,

Thomas.

Thanks Thomas for your time... using 2.7 great!
 
D

dgcosgrave

Hi,



just as a side-note



for word in list:
if word in dict:
count = dict[word]
count += 1
dict[word] = count

dict[word] = 1



When you got the indentation and names right, you can restate this as



import collections

counter = collections.Counter(words)



in Python 2.7 or as



import collections

counter = collections.defaultdict(int)

for word in words:

counter[word] += 1



in Python 2.6



Regards,

Thomas.

Thanks Thomas for your time... using 2.7 great!
 
D

Dennis Lee Bieber

tm =open('ask.txt', 'r')
dict = {}
for line in tm:
line = line.strip()
line = line.translate(None, '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~')
line = line.lower()
list = line.split(' ')

You could (though it gets a bit long) combine some of the above...

list = line.strip().translate(
None,
"the punctuation set"
).lower().split()

# taking advantage that open ()/[]/{} automatically continue on next
lines
for word in list:

INDENTATION! As coded, you first do the strip/translate/lower/split
on EACH line of the file... THEN you are processing the words in the
LAST line processed in the previous loop.
if word in dict:
count = dict[word]
count += 1
dict[word] = count
else:
dict[word] = 1

More indentation -- I suspect your want the else: and following line
to be indented the same as the if line...

Though the whole block can be simplified to

dict[word] = dict.get(word, 0) + 1
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top