How to loop through an object attribute with list comprehension? - python

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.

Related

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.

Create a dictionary using comprehension with nested for loops

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.

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

List of lists of objects to JSON with Python

I have a List with multi lists of objects:
ob = Obj()
for p in l:
list_url_commune = scrapingCities(base_url, p)
for u in list_url_commune:
list_name = scaping_creches(base_url, u, number_page)
list_dep.append(list_name)
json_string = json.dumps([ob.__dict__ for ob in list_dep])
print json_string
list_dep is the list with all the lists with Objects
Then, I would like to convert all the Objects in only one JSON.
In my case, I have an error with json.dumps([ob.__dict__ for ob in list_dep])
(notice: it works fine if I have only one list but here it is a List of lists)
AttributeError: 'list' object has no attribute '__dict__'
Thanks for your help !
Pedro
Just like you noticed yourself, it works fine with a list of objects, but not with a list of lists of objects.
You need to go deeper:
json.dumps([[ob.__dict__ for ob in lst] for lst in list_dep])

Create a list of defaultdict in python

I am doing the following :
recordList=[lambda:defaultdict(str)]
record=defaultdict(str)
record['value']='value1'
record['value2']='value2'
recordList.append(record)
for record in recordList:
params = (record['value'],record['value2'],'31')
i am getting the error :
TypeError: 'function' object is not
subscriptable
what is wrong here ?
recordList=[lambda:defaultdict(str)]
creates a list with a function that returns defaultdict(str). So it's basically equivalent to:
def xy ():
return defaultdict(str)
recordList = []
recordList.append( xy )
As such, when you start your for loop, you get the first element from the list, which is not a list (as all the other elements you push to it), but a function. And a function does not have a index access methods (the ['value'] things).
recordList is a list with 1 element which is a function.
If you replace the first line with
recordList = []
the rest will wor.
you're adding a lambda to recordList, which is of type 'function'. in the for .. loop, you're trying to subscript it (record['value'], record['value2'], etc)
Initialize recordList to an empty list ([]) and it will work.

Categories