Make map () return dictionary

I have the following function:

def heading_positions(self): return map( lambda h: {'{t}.{c}'.format(t=h.table_name,c=h.column_name) : h.position }, self.heading_set.all() ) 

He gives me a conclusion as follows:

 [{'customer.customer_number': 0L}, {'customer.name': 2L}, ... ] 

I would prefer only one dictionary like this:

 {'customer.customer_number': 0L, 'customer.name': 2L, ... 

Is there a way to make map (or something similar) return only one dictionary instead of an array of dictionaries?

+8
python
source share
4 answers

Why use map() then?

 dict( ('{t}.{c}'.format(t=h.table_name, c=h.column_name), h.position) for h in self.heading_set.all() ) 

must work.

+7
source share

Yes. The main problem is that you are not creating a dictionary from a single dict s, but from a sequence of lengths or two sequences (key, value) .

So, instead of creating an independent single-entry dict using the function, create a tuple, and then you can use the dict() constructor:

 dict(map(lambda h: ('{t}.{c}'.format(t=h.table_name, c=h.column_name), h.position), self.heading_set.all())) 

Or directly use the generator or list comprehension inside the dict constructor:

 dict(('{t}.{c}'.format(t=h.table_name, c=h.column_name), h.position) for h in self.heading_set.all()) 

Or in the latest versions (2.7, 3.1) directly understand the dictionary:

 {'{t}.{c}'.format(t=h.table_name : c=h.column_name), h.position) for h in self.heading_set.all()} 
+6
source share
 return dict(('{t}.{c}'.format(t=h.table_name, c=h.column_name), h.position) for h in self.heading_set.all()) 
+2
source share

As the other answers show, you can use dict() .

But as a curiosity, perhaps you can also use reduce

EDIT . As the comment says, dict() is easier in this case. But, just for the sake of theory, I had in mind what can be solved using only functional building blocks (without understanding the magic of the python dictionary):

 def union(d1,d2): result = {} result.update(d1) result.update(d2) return result 

Then:

 reduce(union, sequence_of_dictionaries, {}) 

Alternatively, less clean but more efficient, using an alternative version of dict.update, which returns its first argument:

 def update2(d1, d2): dict.update(d1, d2) return d1 

Or even:

 update2 = lambda d1,d2: (d1, d1.update(d2))[0] 

Then:

 reduce(update2, sequence_of_dictionaries, {}) 

Where in this case sequence_of_dictionaries will be:

 [{'{t}.{c}'.format(t=h.table_name, c=h.column_name) : h.position} for h in self.heading_set.all()] 
+1
source share