List objects are un-hashable

A

Andy

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()
 
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:
....
Hey!
['if(True):print"Hey!"']

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

Alexander Schmolck

Andy said:
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
 
A

Andy

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
 
M

Michael Hoffman

Andy said:
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))
 

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

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top