How to convert for loop to list comprehension - python

a = []
b = {}
for list1 in tasks:
for dict2 in list1:
b.update(dict2)
a.append(b)
How can I write this code as list comprehension?
I tried this but it didn't work:
a = [ [ b.update(dict2) for dict2 in list1 ] for list1 in tasks ]
my json:
tasks = [[{'tuition_eea_amount': '2083', 'tuition_eea_currency': 'EUR', 'tuition_eea_unit': 'year'},
{'tuition_international_amount': '16200', 'tuition_international_currency': 'EUR', 'tuition_international_unit': 'year'}],
[{'tuition_eea_amount': '2083', 'tuition_eea_currency': 'EUR', 'tuition_eea_unit': 'year'},
{'tuition_international_amount': '16200', 'tuition_international_currency': 'EUR', 'tuition_international_unit': 'year'}]]
I want to convert it into:
a = [[{'tuition_eea_amount': '2083', 'tuition_eea_currency': 'EUR', 'tuition_eea_unit': 'year', 'tuition_international_amount': '16200', 'tuition_international_currency': 'EUR', 'tuition_international_unit': 'year'},
{'tuition_eea_amount': '2083', 'tuition_eea_currency': 'EUR', 'tuition_eea_unit': 'year', 'tuition_international_amount': '16200', 'tuition_international_currency': 'EUR', 'tuition_international_unit': 'year'}]]
There should be one list, with two dictionaries inside. But now it is two lists with two dictionaries inside each of them.

It seems like you want to create a merged dict from all dicts in each list in tasks. For thing you can do:
a = [{k: v for dict2 in list1 for k, v in dict2.items()} for list1 in tasks]
In case of repeating keys between the dicts, this will save the last one encountered.
The dict-comp used here is basically the equivalent of using update in a loop. It iterates over all dicts, and for each updates the new dict with all the key: value pairs. Then te list-comp just does that for all sub-lists in tasks.

Related

How can I turn a list of values to a list of dictionaries with the same key added to each value?

Let's say I have this list of IDs/values:
Input:
['aaa','bbb','ccc']
I've been stuck on figuring out how I could get the following list of dictionaries. Each dictionary contain the key "id" paired with each of the IDs/values from the list.
Desired Output:
[{'id': 'aaa'}, {'id': 'bbb'}, '{id': 'ccc'}]
You can create a list of dictionaries with a list comprehension:
list_ = ['aaa','bbb','ccc']
output = [{'id': elem} for elem in list_]
You can use list slicing concepts here to get your result.
list1 = ['aaa','bbb','ccc']
finalOutput = [{'id': value} for value in list1]
you can loop and append those dictionaries to list like this:
some_list = ['aaa', 'bbb', 'ccc']
dictionary_list = []
for i in some_list:
dictionary_list.append({'id': i})
You will get a list like you wanted.
['aaa','bbb','ccc']
#place the word 'ID' in front of each element in the list
['ID: '+x for x in ['aaa','bbb','ccc']]

Sort list in a dict that has key as a list of dicts

I am trying to sort a list by keys of dict that has keys as a lists with other dicts.
big_list = [{"Key1": 1, "Key2" :2, "Key3": [{"sortable_key": value1, value2, ..}]}]
The goal is to sort the big_list by sortable_key. I am trying to accomplish sorting by using lambda:
big_list = list(sorted(big_list, key=lambda x: x["Key3"]["sortable_key"]))
But this is not working (not sorting the list, I assume that it would sort it in particular order like alphabetical). Am I trying to access the sortable_key in a wrong manner or is this not achievable by using lambda?
Thanks!
Full example of big_list:
big_list = [{'number': '7',
'code': '1106',
'name': 'John',
'det': [{'subcode': 'AA11','subname': 'Alan','age': 11},
{'subcode': 'CC11','subname': 'Hugo','age': 22},
{'subcode': 'BB11','subname': 'Walt','age': 18}]}]
In this case I need to sort list by 'subcode'.
You forgot a [0] since x["Key3"]is a list:
big_list = list(sorted(big_list, key=lambda x: x["Key3"][0]["sortable_key"]))

Convert 4 one-to-one mapped lists into a list of dicts (python)

I have 4 lists where the elements are one-to-one mapped. There are tens of thousands of elements. I want to create one dict giving the 4 properties for each element, and then I want to put these dicts into a list. (My end goal is to create a pandas DataFrame and save it as an HDF5 file.)
Is there an easy memory-efficient way to do this, perhaps using zip() and dict() instead of a for loop?
As a working example for Python, please consider:
list1 = ['obj1','obj2','obj3']
list2 = ['cat','dog','tree']
list3 = [7,8,9]
list4 = ['red','green','blue']
So the idea is that in the end I want a list of dicts that looks like
[{'obj':'obj1','type':'cat','num':7,'color':'red'},
{'obj':'obj2','type':'dog','num':8,'color':'green'},
{'obj':'obj3','type':'tree','num':9,'color':'blue'}]
Since you tag pandas , By using to_dict
pd.DataFrame({'obj':list1,'type':list2,'num':list3,'color':list4}).to_dict('r')
Out[1204]:
[{'color': 'red', 'num': 7, 'obj': 'obj1', 'type': 'cat'},
{'color': 'green', 'num': 8, 'obj': 'obj2', 'type': 'dog'},
{'color': 'blue', 'num': 9, 'obj': 'obj3', 'type': 'tree'}]
Here's a non-pandas option:
data = zip(list1, list2, list3, list4)
keys = ['obj', 'type', 'num', 'color']
list_of_dicts = [dict(zip(keys, i)) for i in data]
Instead of a list a dict of dicts
import pandas as pd
import numpy as np
list1 = ['obj1','obj2','obj3']
list2 = ['cat','dog','tree']
list3 = [7,8,9]
list4 = ['red','green','blue']
pd.DataFrame(np.array([list1, list2, list3, list4])).to_dict()
Since it is using corresponding element from each list (first dictionary of the output list is with first element from each input list) and assuming all list are of same size, using list comprehension may be one other way:
[{'obj':list1[i], 'type':list2[i],
'num':list3[i], 'color':list4[i]} for i in range(len(list1))]

Python - Get dictionary element in a list of dictionaries after an if statement

How can I get a dictionary value in a list of dictionaries, based on the dictionary satisfying some condition? For instance, if one of the dictionaries in the list has the id=5, I want to print the value corresponding to the name key of that dictionary:
list = [{'name': 'Mike', 'id': 1}, {'name': 'Ellen', 'id': 5}]
id = 5
if any(m['id'] == id for m in list):
print m['name']
This won't work because m is not defined outside the if statement.
You have a list of dictionaries, so you can use a list comprehension:
[d for d in lst if d['id'] == 5]
# [{'id': 5, 'name': 'Ellen'}]
new_list = [m['name'] for m in list if m['id']==5]
print '\n'.join(new_list)
This will be easy to accomplish with a single for-loop:
for d in list:
if 'id' in d and d['in'] == 5:
print(d['name'])
There are two key concepts to learn here. The first is that we used a for loop to "go through each element of the list". The second, is that we used the in word to check if a dictionary had a certain key.
How about the following?
for entry in list:
if entry['id']==5:
print entry['name']
It doesn't exist in Python2, but a simple solution in Python3 would be to use a ChainMap instead of a list.
import collections
d = collections.ChainMap(*[{'name':'Mike', 'id': 1}, {'name':'Ellen', 'id': 5}])
if 'id' in d:
print(d['id'])
You can do it by using the filter function:
lis = [ {'name': 'Mike', 'id': 1}, {'name':'Ellen', 'id': 5}]
result = filter(lambda dic:dic['id']==5,lis)[0]['name']
print(result)

Merge dictionaries in different lists in Python

I need to merge two lists with dictionaries in them:
dict1 = [{'Count': '307', 'name': 'Other', 'Percentage': '7.7%'}, {'Count': '7,813', 'name': 'Other', 'Percentage': '6.8%'}...]
dict2 = [{'Place': 'Home'}, {'Place':'Forest'},...]
There are 56 elements in the first list (56 dictionaries) and 14 elements in the second list (dict2). What I want to do is inset first element from dict2 to first four elements of dict 1 and repeat the process until all 56 elements in dict1 have {Place:x}.
So eventually what I want to get is:
newdict = [{'Count': '307', 'name': 'Other', 'Percentage': '7.7%', 'Place': 'Home'}, {'Count': '7,813', 'name': 'Other', 'Percentage': '6.8%', 'Place':'Home'},{'Name': 'Other', 'Percentage': '6.6%', 'Place': 'Home', 'Count': '1,960'},{'Name': 'Other', 'Percentage': '7.6%', 'Place': 'Home', 'Count': '1,090'},{'Name': 'Other', 'Percentage': '7.6%', 'Place': 'Forest', 'Count': '1,090'} ]
and so on..
When dict2 is exhausted, it should start from first element again.
So I updated question. My first take on this problem was to increase number of same key:values in dict2 to:
dict2 = [{'Place': 'Home'}, {'Place':'Home'},{'Place':'Home'},{'Place':'Home'},{'Place':'Forest'},{'Place':'Forest'}...]
and then use the same method mentioned below to merge dictionaries. But I believe there should be a way to do this without changing dict2.
We'll use zip and itertools.cycle to pair up elements from the two lists.
from itertools import cycle
for a, b in zip(dict1, cycle(dict2)):
a.update(b)
If you don't want to modify the original list, it's a little more complex.
from itertools import cycle, chain
new_list = [{k:v for k, v in chain(a.items(), b.items())} for a, b in zip(dict1, cycle(dict2))]
You can use zip():
res = []
for i, j in zip(dict1, dict2):
res.append(i)
res[-1].update(j)
If the number of items in your dicts are not the same, you can use itertools.izip_longest() with fillvalue param set to {}:
res = []
for i, j in itertools.izip_longest(dict1, dict2, fillvalue={}):
res.append(i)
res[-1].update(j)
Using modulo:
new_list = []
x = len(dict2)
for v, item in enumerate(dict1):
z = item.copy()
z['Place'] = dict2[v % x]['Place']
new_list.append(z)
How about simply creating an empty dictionary called result and simply updating it with the list of existing dictionaries you want merged, for example:
def merge_dicts(*dict_args):
"""
Given any number of dicts, shallow copy and merge into a new dict,
precedence goes to key value pairs in latter dicts.
:param dict_args: a list of dictionaries
:return: dict - the merged dictionary
"""
result = {}
for dictionary in dict_args:
result.update(dictionary)
return result

Categories

Resources