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

Discussion in 'Python' started by Token Type, Sep 8, 2012.

  1. Token Type

    Token Type Guest

    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?

    >>> def average_polysemy(pos):

    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)

    >>> average_polysemy('n')


    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
    Token Type, Sep 8, 2012
    #1
    1. Advertising

  2. Token Type

    Token Type Guest

    wordnet NLTK Re: AttributeError: 'list' object has no attribute 'lower'

    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:

    >>> def average_polysemy(pos):

    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)

    >>> average_polysemy('n')

    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?
    >
    >
    >
    > >>> def average_polysemy(pos):

    >
    > 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)
    >
    >
    >
    > >>> average_polysemy('n')

    >
    >
    >
    > 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
    Token Type, Sep 8, 2012
    #2
    1. Advertising

  3. Token Type

    Roy Smith Guest

    In article <>,
    Token Type <> wrote:

    > 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.



    > 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)
    >
    > >>> average_polysemy('n')

    >
    > 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
    Roy Smith, Sep 8, 2012
    #3
  4. On 08Sep2012 13:45, Roy Smith <> wrote:
    | First, I don't understand this code:
    |
    | In article <>,
    | Token Type <> wrote:
    | > 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,
    --
    Cameron Simpson <>

    Too much of a good thing is never enough. - Luba
    Cameron Simpson, Sep 9, 2012
    #4
  5. Token Type

    Token Type Guest

    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:

    >>> def average_polysemy(pos):

    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)

    >>> average_polysemy('n')

    3

    Thanks again.
    Token Type, Sep 9, 2012
    #5
  6. Token Type

    Token Type Guest


    > 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.
    Token Type, Sep 9, 2012
    #6
  7. Token Type

    Token Type Guest


    > structures are simple, just plain print will work, but for more
    >
    > complicated structures, pprint.pprint() is a life saver.
    >


    I did try . However,

    >>> pprint.pprint(lemma_list)


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


    Traceback (most recent call last):
    File "<pyshell#75>", line 1, in <module>
    pprint.pprint(synset_list)
    NameError: name 'pprint' is not defined
    >>>
    Token Type, Sep 9, 2012
    #7
  8. Token Type

    Roy Smith Guest

    In article <>,
    Token Type <> wrote:

    > 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.


    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)
    Roy Smith, Sep 9, 2012
    #8
  9. Token Type

    Roy Smith Guest

    In article <>,
    Token Type <> wrote:

    > > structures are simple, just plain print will work, but for more
    > >
    > > complicated structures, pprint.pprint() is a life saver.
    > >

    >
    > I did try . However,
    >
    > >>> pprint.pprint(lemma_list)

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

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


    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)
    Roy Smith, Sep 9, 2012
    #9
  10. Token Type wrote:
    >> 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.
    >


    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
    Jean-Michel Pichavant, Sep 10, 2012
    #10
  11. Token Type

    Token Type Guest

    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.
    Token Type, Sep 14, 2012
    #11
  12. Token Type

    Token Type Guest

    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.
    Token Type, Sep 14, 2012
    #12
  13. On Fri, 14 Sep 2012 08:01:11 -0700, Token Type wrote:

    > 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.


    --
    Steven
    Steven D'Aprano, Sep 14, 2012
    #13
  14. On Sat, Sep 15, 2012 at 1:01 AM, Token Type <> wrote:
    > 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
    Chris Angelico, Sep 14, 2012
    #14
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. dont bother
    Replies:
    3
    Views:
    4,197
    scriber
    Mar 31, 2009
  2. Earl
    Replies:
    2
    Views:
    3,054
    Peter Otten
    May 6, 2004
  3. adrian
    Replies:
    4
    Views:
    726
    John J. Lee
    Apr 1, 2005
  4. rsd
    Replies:
    2
    Views:
    484
  5. crystalattice
    Replies:
    2
    Views:
    373
    crystalattice
    Sep 1, 2006
Loading...

Share This Page