James Hanks James Hanks - 3 months ago 11
Python Question

What is the difference between these two lists?

I have a list of dictionaries, and in these dictionaries, there sometimes occurs a particular key. This particular key may have a dictionary as its value, and in that dictionary is a key-value pair of interest. Alternatively, the particular key may contain a list of dictionaries with contain the key-value pair of interest.
In the course of trying to get the values of interest in a list, I ran into a more basic problem: when I tried to make a list such as the one described above, I got a type error.

So I cut down a list from the real data to be as minimal as possible, and the list was created as expected. Perhaps I have simply been awake too long, but I cannot for the life of me see the difference between the list that creates and the one that doesn't.

bad_list = list[{'info1':'infoA', 'info2':'infoB'},
{'info1':'infoC', 'info2':'infoD', 'a_dictionary':{'of_interest':'item1','not_interesting':'item1a'}},
{'info1':'infoE', 'info2':'infoF', 'stuff_I_want':{'dlist1': [{'of_interest':'item2', 'not_of_interest':'item3'}, {'of_interest':'item4', 'not_of_interest':'item5'}],'dlist2':[{'of_interest':'item6','not_of_interest':'item7','dont_care':'about_this'},{'of_interest':'item8', 'not_interesting':'item9'}]}}]


gives

Traceback (most recent call last):
File "C:\Users\user1\Anaconda2\lib\site-packages\IPython\core\interactiveshell.py", line 2885, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-426-5b36ee39e1b4>", line 3, in <module>
{'info1':'infoE', 'info2':'infoF', 'stuff_I_want':{'dlist1':[{'of_interest':'item2', 'not_of_interest':'item3'}, {'of_interest':'item4', 'not_of_interest':'item5'}],'dlist2':[{'of_interest':'item6','not_of_interest':'item7','dont_care':'about_this'},{'of_interest':'item8', 'not_interesting':'item9'}]}}]
TypeError: 'type' object has no attribute '__getitem__'


but:

good_list = [{u'_score': 22.789707, u'symbol': u'RP4-669L17.10', u'_id': u'ENSG00000237094', u'query': u'ENSG00000237094'},
{u'pfam': u'PF03715', u'name': u'NOC2 like nucleolar associated transcriptional repressor', u'_score': 22.789707, u'symbol': u'NOC2L', u'go': {u'CC': [{u'term': u'nucleus', u'pubmed': [16322561, 20959462], u'id': u'GO:0005634', u'evidence': u'IDA'}, {u'term': u'nucleoplasm', u'pubmed': 20123734, u'id': u'GO:0005654', u'evidence': u'IDA'}], u'MF': [{u'term': u'chromatin binding', u'pubmed': [16322561, 20123734], u'id': u'GO:0003682', u'evidence': u'IDA'}, {u'term': u'transcription corepressor activity', u'pubmed': 16322561, u'id': u'GO:0003714', u'evidence': u'IDA'}]}, u'query': u'ENSG00000188976', u'_id': u'26155'},
{u'pfam': u'PF00858', u'name': u'sodium channel epithelial 1 delta subunit', u'_score': 22.79168, u'symbol': u'SCNN1D', u'go': {u'CC': [{u'term': u'plasma membrane', u'id': u'GO:0005886', u'evidence': u'IDA'}, {u'term': u'plasma membrane', u'id': u'GO:0005886', u'evidence': u'TAS'}]}}]


creates the expected list without dictionaries.

What is different about the structure of these two lists that makes one legal and the other not? I have a feeling I'm missing something silly, but I just can't see it.

Answer

You don't need list[] to construct a list. It doesn't construct a list. It tries to extract an element from the concept of a list. I think what you meant was list() but that's just more verbose and less clear.

[] gets an item from an object. list[] tries to access an item from the list data type.

list[1] is like saying "Okey, get the first item from the list." The interpreter asks "Which list?", and you respond "the very concept of a list". And then the interpreter responds with a error saying "the very concept of a list isn't a list".


In Depth

Saying some_object[index] is equivalent (syntactic sugar) for some_object.__getitem__(index). So if a datatype wants to let you subscript ([index]) it, the datatype will define a __getitem__.

But the type of the type (yes - even types have types) don't want you to be able to subscript types themselves, so the type type doesn't define a __getitem__.

Comments