AttributeError: 'list' object has no attribute 'lower'

T

Token Type

On page 77 of the book natural language processing with Python, we have such an exercise: The polysemy of a word is the number of senses it has. Using WordNet, we can determine that the noun doghas seven senses with len(wn.synsets('dog', 'n')).
Compute the average polysemy of nouns, verbs, adjectives, and adverbs according
to WordNet.http://nltk.googlecode.com/svn/trunk/doc/book/ch02.html

I wrote the following function to solve it. However, it pops up "AttributeError: 'list' object has no attribute 'lower'". Quite confused, I supposed [synset.lemma_names for synset in synset_list] has made all the lemma into a list, hasn't it?
synset_list = list(wn.all_synsets(pos))
lemma_list = [synset.lemma_names for synset in synset_list]
sense_number = 0
for lemma in lemma_list:
sense_number_new = len(wn.synsets(lemma, pos))
sense_number = sense_number + sense_number_new
return sense_number/len(synset_list)

Traceback (most recent call last):
File "<pyshell#54>", line 1, in <module>
average_polysemy('n')
File "<pyshell#53>", line 6, in average_polysemy
sense_number_new = len(wn.synsets(lemma, pos))
File "C:\Python27\lib\site-packages\nltk\corpus\reader\wordnet.py", line 1191, in synsets
lemma = lemma.lower()
AttributeError: 'list' object has no attribute 'lower'

Thanks for your tips
 
T

Token Type

I don't know why lemma_list = [synset.lemma_names for synset in synset_list] will lead to such an error.

I have to use extend to solve the problem for lemma_list. The following codes are successful, take all the nouns as an example:
synset_list = list(wn.all_synsets(pos))
sense_number = 0
lemma_list = []
for synset in synset_list:
lemma_list.extend(synset.lemma_names)
for lemma in lemma_list:
sense_number_new = len(wn.synsets(lemma, pos))
sense_number = sense_number + sense_number_new
return sense_number/len(synset_list)
3


I wrote the following function to solve it. However, it pops up "AttributeError: 'list' object has no attribute 'lower'". Quite confused, I supposed [synset.lemma_names for synset in synset_list] has made all the lemma into a list, hasn't it?



synset_list = list(wn.all_synsets(pos))

lemma_list = [synset.lemma_names for synset in synset_list]

sense_number = 0

for lemma in lemma_list:

sense_number_new = len(wn.synsets(lemma, pos))

sense_number = sense_number + sense_number_new

return sense_number/len(synset_list)





Traceback (most recent call last):

File "<pyshell#54>", line 1, in <module>

average_polysemy('n')

File "<pyshell#53>", line 6, in average_polysemy

sense_number_new = len(wn.synsets(lemma, pos))

File "C:\Python27\lib\site-packages\nltk\corpus\reader\wordnet.py", line 1191, in synsets

lemma = lemma.lower()

AttributeError: 'list' object has no attribute 'lower'



Thanks for your tips
 
R

Roy Smith

Token Type said:
I wrote the following function to solve it. However, it pops up
"AttributeError: 'list' object has no attribute 'lower'". Quite confused, I
supposed [synset.lemma_names for synset in synset_list] has made all the
lemma into a list, hasn't it?

I'm not familiar with that library, but here's a few general ideas to
help you figure out what's going on.

First, I don't understand this code:
synset_list = list(wn.all_synsets(pos))
lemma_list = [synset.lemma_names for synset in synset_list]

It looks like you're taking an iterable, converting it to a list, just
so you can iterate over it again. Why not the simpler:
lemma_list = [synset.lemma_names for synset in wn.all_synsets(pos)]

? But, I'm also confused about what lemma_list is supposed to end up
being. The name "lemma_names" is plural, making me think it returns a
list of something. And then you build those up into a list of lists?

In fact, I'm guessing that's your problem. I think you're ending up
with a list of lists of strings, when you think you're getting a list of
strings.

My suggestion is to print out all the intermediate data structures
(synset_list, lemma_list, etc) and see what they look like. If the
structures are simple, just plain print will work, but for more
complicated structures, pprint.pprint() is a life saver.

Another possibility is to assert that things are what you expect them to
be. Something like:

assert isinstance(synset_list, list)
assert isinstance(lemma_list, list)
assert isinstance(lemma_list[0], str)

and so on.
 
C

Cameron Simpson

| First, I don't understand this code:
|
| In article <[email protected]>,
| > synset_list = list(wn.all_synsets(pos))
| > lemma_list = [synset.lemma_names for synset in synset_list]
|
| It looks like you're taking an iterable, converting it to a list, just
| so you can iterate over it again. Why not the simpler:
|
| > lemma_list = [synset.lemma_names for synset in wn.all_synsets(pos)]

Speaking for myself, when I write something like that it is because I
need to iterate over it twice or more. Often I'll make a tuple instead
of a list in that case, too, to avoid certain types of accidents.

| ? But, I'm also confused about what lemma_list is supposed to end up
| being. The name "lemma_names" is plural, making me think it returns a
| list of something. And then you build those up into a list of lists?
|
| In fact, I'm guessing that's your problem. I think you're ending up
| with a list of lists of strings, when you think you're getting a list of
| strings.

In my case, I have most often had this error (<list>.lower or its
equivalent) when I've accidentally converted a string into a list
of characters; easy to do because strings are themselves iterables,
yielding a sequence of single character strings:)

It is usually an accident from getting my nesting wrong somewhere.

| My suggestion is to print out all the intermediate data structures
| (synset_list, lemma_list, etc) and see what they look like. If the
| structures are simple, just plain print will work, but for more
| complicated structures, pprint.pprint() is a life saver.
|
| Another possibility is to assert that things are what you expect them to
| be. Something like:
|
| assert isinstance(synset_list, list)
| assert isinstance(lemma_list, list)
| assert isinstance(lemma_list[0], str)
|
| and so on.

+1 to all of this, too.

Cheers,
 
T

Token Type

Thanks very much for all of your tips. Take noun as an example. First, I need find all the lemma_names in all the synsets whose pos is 'n'. Second, for each lemma_name, I will check all their sense number.

1) Surely,we can know the number of synset whose pos is noun by
len([synset for synset in wn.all_synsets('n')])
82115

However, confusingly it is unsuccessful to get a list of lemma names of these synsets by
lemma_list = [synset.lemma_names for synset in wn.all_synsets('n')]
lemma_list[:20] [['entity'], ['physical_entity'], ['abstraction', 'abstract_entity'], ['thing'], ['object', 'physical_object'], ['whole', 'unit'], ['congener'], ['living_thing', 'animate_thing'], ['organism', 'being'], ['benthos'], ['dwarf'], ['heterotroph'], ['parent'], ['life'], ['biont'], ['cell'], ['causal_agent', 'cause', 'causal_agency'], ['person', 'individual', 'someone', 'somebody', 'mortal', 'soul'], ['animal', 'animate_being', 'beast', 'brute', 'creature', 'fauna'], ['plant', 'flora', 'plant_life']]
type(lemma_list)
<type 'list'>

Though the lemma_list is a list in the above codes, it contains so many unnecessary [ and ]. How come it is like this? But what we desire and expect is a list without this brackets. Confused, I am really curious to know why.

2) Then I have to use a loop and extend to get all the lemma_names from synset:
synset_list = list(wn.all_synsets('n'))
lemma_list = []
for synset in synset_list: lemma_list.extend(synset.lemma_names)
lemma_list[:20]
['entity', 'physical_entity', 'abstraction', 'abstract_entity', 'thing', 'object', 'physical_object', 'whole', 'unit', 'congener', 'living_thing', 'animate_thing', 'organism', 'being', 'benthos', 'dwarf', 'heterotroph', 'parent', 'life', 'biont']

3) In this case, I have to use loop to get all the lemma_names instead of [synset.lemma_names for synset in wn.all_synsets('n')]. The following is a working solution:
synset_list = list(wn.all_synsets(pos))
sense_number = 0
lemma_list = []
for synset in synset_list:
lemma_list.extend(synset.lemma_names)
for lemma in lemma_list:
sense_number_new = len(wn.synsets(lemma, pos))
sense_number = sense_number + sense_number_new
return sense_number/len(synset_list)
3

Thanks again.
 
T

Token Type

In fact, I'm guessing that's your problem. I think you're ending up

with a list of lists of strings, when you think you're getting a list of

strings.
Thanks. You guess right. It turns out that lemma_list is a list of list, as I tested in the previous post.
 
T

Token Type

structures are simple, just plain print will work, but for more

complicated structures, pprint.pprint() is a life saver.

I did try . However,

Traceback (most recent call last):
File "<pyshell#74>", line 1, in <module>
pprint.pprint(lemma_list)
NameError: name 'pprint' is not defined
Traceback (most recent call last):
File "<pyshell#75>", line 1, in <module>
pprint.pprint(synset_list)
NameError: name 'pprint' is not defined
 
R

Roy Smith

Token Type said:
Thanks very much for all of your tips. Take noun as an example. First, I need
find all the lemma_names in all the synsets whose pos is 'n'. Second, for
each lemma_name, I will check all their sense number.

1) Surely,we can know the number of synset whose pos is noun by
len([synset for synset in wn.all_synsets('n')])
82115

However, confusingly it is unsuccessful to get a list of lemma names of these
synsets by
lemma_list = [synset.lemma_names for synset in wn.all_synsets('n')]
lemma_list[:20]
[['entity'], ['physical_entity'], ['abstraction', 'abstract_entity'],
['thing'], ['object', 'physical_object'], ['whole', 'unit'], ['congener'],
['living_thing', 'animate_thing'], ['organism', 'being'], ['benthos'],
['dwarf'], ['heterotroph'], ['parent'], ['life'], ['biont'], ['cell'],
['causal_agent', 'cause', 'causal_agency'], ['person', 'individual',
'someone', 'somebody', 'mortal', 'soul'], ['animal', 'animate_being',
'beast', 'brute', 'creature', 'fauna'], ['plant', 'flora', 'plant_life']]<type 'list'>


Though the lemma_list is a list in the above codes, it contains so many
unnecessary [ and ]. How come it is like this? But what we desire and expect
is a list without this brackets. Confused, I am really curious to know why.

It looks like synset.lemma_names gets you a list. And then you're
taking all those lists and forming them into a list of lists:
lemma_list = [synset.lemma_names for synset in wn.all_synsets('n')]

I think what you want to study is the difference between list.append()
and list.extend(). When you use the list builder syntax, you're
essentially writing a loop which does append operations. The above is
the same as if you wrote:

lemma_list = list()
for synset in wn.all_synsets('n'):
lemma_list.append(synset.lemma_names)

and I think what you're looking for is:

lemma_list = list()
for synset in wn.all_synsets('n'):
lemma_list.extend(synset.lemma_names)
 
R

Roy Smith

structures are simple, just plain print will work, but for more

complicated structures, pprint.pprint() is a life saver.

I did try . However,

Traceback (most recent call last):
File "<pyshell#74>", line 1, in <module>
pprint.pprint(lemma_list)
NameError: name 'pprint' is not defined
Traceback (most recent call last):
File "<pyshell#75>", line 1, in <module>
pprint.pprint(synset_list)
NameError: name 'pprint' is not defined[/QUOTE]

OK, I can see how this can be confusing. In "pprint.pprint()", the two
"pprint"s mean different things. The first one is the name of a module.
The second one is the name of a function in that module. In general, I
dislike this style of naming since it just leads to this kind of
confusion.

In any case, you need to do one of two things.

Style 1:

import pprint
pprint.pprint(foo)

Style 2:

from pprint import pprint
pprint(foo)
 
J

Jean-Michel Pichavant

Token said:
Thanks. You guess right. It turns out that lemma_list is a list of list, as I tested in the previous post.

I often noticed people around me that are not that familiar with python
are dismissing the error stack so quickly ; they probably knows the
machine is trying to communicate with them but they don't seem to
understand the message. Error stacks may be difficult to read at first
glance but you can solve a lot of problems just by reading it.

So next time you see 'X' has no attribute 'Y', you'll know that you've
accessed an attribute/method of an object that does not exist, either
you made a typo in the attribute name, or you object is not actually
what you think it is.

Advice : if you have so time, install ipython and execute your scripts
in an ipython shell with the %pdb faeture on. This will automatically
call the debugger upon unhandled exceptions and you'll be able to
inspect your objects live from the prompt.

JM
 
T

Token Type

Thanks. By the way, do we have a list of explanations of error message? If so, whenever we come across error message, we can refer to it and solve the problem accordingly.
 
T

Token Type

Thanks. By the way, do we have a list of explanations of error message? If so, whenever we come across error message, we can refer to it and solve the problem accordingly.
 
S

Steven D'Aprano

Thanks. By the way, do we have a list of explanations of error message?
If so, whenever we come across error message, we can refer to it and
solve the problem accordingly.

Forget about a "list of explanations of error message". There is no
such list, and there never will be, because there is no limit to the
number and kind of possible error messages.

Instead, you should actually read the error message you see. Python is
telling you what the problem is. Pay attention to it.

AttributeError: 'list' object has no attribute 'lower'

This tells you that you tried to access something.lower, but "something"
is a list, and lists don't have an attribute or method "lower".

Normally, Python will show you the line of source code with the error, so
you will even see the name of the variable.
 
C

Chris Angelico

Thanks. By the way, do we have a list of explanations of error message? If so, whenever we come across error message, we can refer to it and solve the problem accordingly.

Not really, but if you paste the message into Google or DuckDuckGo or
another web search engine, you'll usually find something helpful.
Possibly add a few keywords about what you're doing, if the message
alone is too general.

By the way, you don't need to include both comp.lang.python and
python-list in your addressees; they mirror each other, so sending to
one will make it arrive on the other too.

Have fun!

ChrisA
 

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,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top