By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,772 Members | 919 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,772 IT Pros & Developers. It's quick & easy.

List objects are un-hashable

P: n/a
Hi, I'm trying to search and print any no# of Python keywords present
in a text file (say - foo.txt), and getting the above error. Sad for
not being able to decipher such a simple problem (I can come up with
other ways - but want to fix this one FFS). Any help is appreciated.
Thanks!!

import keyword, re, sys, string
inp = open("foo.txt", "r")
words,lines = 0, 0

for line in inp:
lines +=1
# a list of words
tempwords = line.split(None)
if keyword.iskeyword(tempwords):
print tempwords

inp.close()

Apr 27 '07 #1
Share this Question
Share on Google+
7 Replies


P: n/a
Andy <an***********@gmail.comwrites:
Hi, I'm trying to search and print any no# of Python keywords present
in a text file (say - foo.txt), and getting the above error. Sad for
not being able to decipher such a simple problem (I can come up with
Without looking at the docs, it seems save to assume keywords.iskeyword would
expect a string. You pass it a list.
other ways - but want to fix this one FFS). Any help is appreciated.
Thanks!!

import keyword, re, sys, string
inp = open("foo.txt", "r")
words = sum(1 for line in inp for w in line.split() if keyword.iskeyword(w))

'as
Apr 27 '07 #2

P: n/a
Ant
for line in inp:
lines +=1
# a list of words
tempwords = line.split(None)
if keyword.iskeyword(tempwords):
print tempwords
You are trying here to ask if a list of words (tempwords) is a
keyword. The error is due to the implementation of the iskeyword
function which converts the keyword list into a frozenset (in which
elements must be hashable) for, I presume, performance reasons:
>>f_set = frozenset((1,2,3,4))
["test"] in f_set
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: list objects are unhashable

What you want is something like:

for line in inp:
lines +=1
# a list of words
tempwords = line.split()
for k in tempwords:
if keyword.iskeyword(k):
print tempwords

Which iterates over each word in your tempwords list in turn. Note
though the following:
>>if(True):print"Hey!"
....
Hey!
>>s = 'if(True):print"Hey!"'
s.split()
['if(True):print"Hey!"']

Which may be a problem for you if you are trying to parse badly spaced
python source files!

Apr 27 '07 #3

P: n/a
What you want is something like:

for line in inp:
lines +=1
# a list of words
tempwords = line.split()
for k in tempwords:
if keyword.iskeyword(k):
print tempwords

I think it should be:

if keyword.iskeyword(k):
print k

Apr 27 '07 #4

P: n/a
Ant
I think it should be:
>
if keyword.iskeyword(k):
print k
Whoops - yes of course!

Apr 27 '07 #5

P: n/a
>>>>"Andy" == Andy <an***********@gmail.comwrites:
if keyword.iskeyword(tempwords):
print tempwords
for word in tempwords:
if keyword.iskeyword(word):
print word

Ganesan
--
Ganesan Rajagopal

Apr 27 '07 #6

P: n/a
Andy wrote:
Hi, I'm trying to search and print any no# of Python keywords present
in a text file (say - foo.txt), and getting the above error. Sad for
not being able to decipher such a simple problem (I can come up with
other ways - but want to fix this one FFS).
It helps a lot of if you post the traceback with your problem. The line
it occurred on is crucial for debugging.

But I will use my psychic debugger which tells me that the error is here:
if keyword.iskeyword(tempwords):
tempwords is a list. You need to iterate over the contents of the list
and run keyword.iskeyword() for each one. Here's an example for Python
2.5. I've cleaned up some extra lines of code that didn't have any
eventual effects in your current implementation

from __future__ import with_statement

import keyword

INFILENAME = "foo.txt"

with open(INFILENAME) as infile:
for line in infile:
words = line.split()
for word in words:
if keyword.iskeyword(word):
print word

This will print multiple lines per input line. If you wanted one line
per input line then try:

with open(INFILENAME) as infile:
for line in infile:
words = line.split()
print " ".join(word for word in words
if keyword.iskeyword(word))
--
Michael Hoffman
Apr 27 '07 #7

P: n/a
Thanks Michael and Ant.

Apr 29 '07 #8

This discussion thread is closed

Replies have been disabled for this discussion.