Create a dictionary using comprehension with nested for loops - python

I have a nested for loop in which I am setting the key, value for my new dictionary. Having found out about list comprehensions, I'm wondering if it's possible to use the same logic for a dictionary.
My attempt at one line comprehension for the dictionary which currently fails:
dict_contract_name_id = {each_contract: each_contract.id for each_inuring_layer in context.program_obj.inuringLayers for each_contract in each_inuring_layer.contracts}
It fails by saying TypeError: unhashable type: 'ContractWithId'.
Actual code I'm trying to convert to one line comprehension:
dict_contract_name_id = {}
for each_inuring_layer in context.program_obj.inuringLayers:
for each_contract in each_inuring_layer.contracts:
if each_contract.name in contracts:
dict_contract_name_id[each_contract.name] = each_contract.id

You forgot the .name attribute, as well as the if filter:
dict_contract_name_id = {
each_contract.name: each_contract.id
for each_inuring_layer in context.program_obj.inuringLayers
for each_contract in each_inuring_layer.contracts
if each_contract.name in contracts}
You tried to use the each_contract object as a key, and not just the name.

Related

How to loop through an object attribute with list comprehension?

I have a list - list_of_objects = [<obj1>,<obj2>]. Each object has an attribute <ob1j>.content. Each content attribute holds a list of dictionaries [{"key":"value"}, {"key":"value"}]. How do I use list comprehension to "unpack" these dictionaries into a single list? Example that doesn't work:
list_of_dictionaries = [dict for obj in list_of_objects for item in obj.content]
Basically I want to turn the below loop that works into a comprehension:
for obj in list_of_objects:
new_list.extend(obj.content)
Calling dir on the object gives you back all the attributes of that object, including python special attributes.You can always filter out the special methods by using a list comprehension.

Access list from a function

I have created a function which returns a list
def GetAddressContainer(obj,obj1):
mylist = list()
for i in test['adresss']:
addresscotainer = i[id]
return mylist(addresscontainer)
When i call the function -
UkContainer = GetAddressContainer(Postcode,Country)
i get the following error message:
TypeError: 'list' object is not callable in python
Any ideas why i am getting this error and what i would have to update?
The problems seem to be in
return mylist(addresscontainer)
You using parentheses on the list and therefore calling it as a function, that's why you get the error. Without any more code I not entirely sure what to replace it with though.
Issues
The line mylist = list() basically creates an empty list which you can use to store any values. In the code mylist is being called (using (...)) which does not make sense in python since mylist is not a function.
Another issue with the code is that the value of addresscontainer is never being inserted into mylist.
Possible Solutions
So, as per your problem, either of the following solutions can be used:
Append addresscontainer into mylist iteratively within the for loop:
for i in test['adress']:
addresscontainer = i[id]
mylist.append(addresscontainer) # Inserts the value at the end of list
return mylist # Returns the list
[RECOMMENDED] Use list comprehension:
def GetAddressContainer(...):
return [i[id] for i in test['adress']] # Build list using "List Comprehension"
Replace mylist(addresscontainer) with list(addresscontainer) code.
Only list word could be a callable function because it defines a class of any list. And mylist = list() will be an instance of an abstract list, then, not callable.
change mylist = list() to mylist = []
it will create an empty list instead of a list object.
and you are not appending anything to the list.

Python : AttributeError: 'int' object has no attribute 'append'

I have a dict of int, list. What I'm trying to do is loop through `something' and if the key is present in the dict add the item to the lsit or else create a new list and add the item.
This is my code.
levels = {}
if curr_node.dist in levels:
l = levels[curr_node.dist]
l.append(curr_node.tree_node.val)...........***
else:
levels[curr_node.dist] = []
levels[curr_node.dist].append(curr_node.tree_node.val)
levels[curr_node.dist] = curr_node.tree_node.val
My question is two-fold.
1. I get the following error,
Line 27: AttributeError: 'int' object has no attribute 'append'
Line 27 is the line marked with ***
What am I missing that's leading to the error.
How can I run this algorithm of checking key and adding to a list in a dict more pythonically.
You set a list first, then replace that list with the value:
else:
levels[curr_node.dist] = []
levels[curr_node.dist].append(curr_node.tree_node.val)
levels[curr_node.dist] = curr_node.tree_node.val
Drop that last line, it breaks your code.
Instead of using if...else, you could use the dict.setdefault() method to assign an empty list when the key is missing, and at the same time return the value for the key:
levels.setdefault(curr_node.dist, []).append(curr_node.tree_node.val)
This one line replaces your 6 if: ... else ... lines.
You could also use a collections.defaultdict() object:
from collections import defaultdict
levels = defaultdict(list)
and
levels[curr_node.dist].append(curr_node.tree_node.val)
For missing keys a list object is automatically added. This has a downside: later code with a bug in it that accidentally uses a non-existing key will get you an empty list, making matters confusing when debugging that error.

python dictionary update methods to extend dictionary

So i am using dictionary within a dictionary and every time I would try to extend the child_dict, which i do using a loop, only the last iteration value persists while the previous ones are over-written
parent_dict = defaultdict(list)
for getdata from datasource:
# I generate 'child_dict' here
parent_dict[parentDict_key] = child_dict
I tried to use .update(child_dict) method but it gives me
AttributeError: 'list' object has no attribute 'update'
I also tried to use .append() method but it makes the parent a list of dictionaries.
Is there any better way to add new child_dict to my parent_dict and just extend it during each iteration?
Well, if you want your values to be dictionaries and not lists you should use:
parent_dict = defaultdict(dict)
instead of:
parent_dict = defaultdict(list)
and then to generate:
parent_dict[parentDict_key][child_dict_key] = child_dict_value

Add dictionary as value of dictionary in Python

I want to create a array of set in Python.
That is what i am trying to do with my code below
for doc in collection.find():
pageType = doc.get('pageType')
title = doc.get('title')
_id = doc.get('_id')
value = {'pageType' : pageType, 'id': _id}
setValues = pageDict.get(title)
if not setValues :
setValues = set()
pageDict[title] = setValues
setValues.add(value)
I get following error when running it
setValues.add(value)
TypeError: unhashable type: 'dict'
I found that i cannot set the mutable value as a key of the dictionary, but i am here adding it as value of dictionary. Essentially, my value of dictionary is a set which contains another dictionary.
How can i achieve this in python? What other data structures can i used to achieve this?
i used frozsenSet to add the value to the set and it worked
setValues.add(frozenSet(value.items())

Categories