I have a list like this:
original_list= ['A', 'B', 'C', 'D', 'E']
How would I be able to write a function to convert it into this:
converted_list= [{'A': 1}, {'B': 1}, {'C': 1}, {'D': 1}, {'E': 1}]
All the values in each dictionary are 1.
Thank you!
Use a list comprehension:
converted_list = [{s: 1} for s in original_list]
Related
Suppose I have the following data frame:
df = pd.DataFrame({'a': [1,1,1,2], 'b': ['a', 'a', 'b', 'c'], 'd': [1, 2, 3, 4]})
And I want to end with the following dict:
{1: [{'b':'a', 'd': 1}, {'b': 'a', 'd': 2}, {'b': 'b', 'd': 3}], 2: [{'b': 'c', 'd': 4}]}
Basically, I want to group by a and for each data frame I want to apply to_dict('records').
What I tried was the following:
# dict ok but not a list
df.groupby('a').agg(list).to_dict('index')
{1: {'b': ['a', 'a', 'b'], 'd': [1, 2, 3]}, 2: {'b': ['c'], 'd': [4]}}
# the index disappears
df.groupby('a').agg(list).to_dict('records')
[{'b': ['a', 'a', 'b'], 'd': [1, 2, 3]}, {'b': ['c'], 'd': [4]}]
df.set_index('a').to_dict('index')
ValueError: DataFrame index must be unique for orient='index'
I think I can do it using a for-loop but I'm almost sure there is a pythonic way to do it.
You could do:
df.assign(dicts=df.drop(columns="a").to_dict("records")).groupby("a")["dicts"].agg(
list
).to_dict()
Here is a way using groupby() and apply()
df.groupby('a').apply(lambda x: x[['b','d']].to_dict('records')).to_dict()
Output:
{1: [{'b': 'a', 'd': 1}, {'b': 'a', 'd': 2}, {'b': 'b', 'd': 3}],
2: [{'b': 'c', 'd': 4}]}
Following your logic, I think one way to avoid a for-loop, is to use GroupBy.apply with zip inside a listcomp to iterate over both columns in // :
out = df.groupby("a").apply(lambda x: [{"b": y, "d": z}
for y, z in zip(x["b"], x["d"])]).to_dict()
If you need to zip more than two columns (dynamically), use this variant :
out = df.groupby("a").apply(lambda x: [dict(zip(x.columns[1:], row))
for row in x[x.columns[1:]].to_numpy()]).to_dict()
Output :
print(out)
#{1: [{'b': 'a', 'd': 1}, {'b': 'a', 'd': 2}, {'b': 'b', 'd': 3}], 2: [{'b': 'c', 'd': 4}]}
I have a complex data structure consisting of list of dictionaries and these dictionaries consists of list of dictionaries further. Now, I am trying to extract specific key:value pairs from internal nested dicts (from list of dictionaries). Hopefully below example shows what I am trying to achieve
complex_data =
[[{'A': 'test1'},
{'A': 'test2'},
{'B': [{'C': {'testabc': {'A': 'xxx'}}},
{'C': {'test123': {'A': 'yyy'}, 'test456': {'A': '111abc'}}},
{'C': {'test123': {'A': 'yyy'}, 'test456': {'A': '111def'}}}]}],
.
.
[{'A': 'test11'},
{'A': 'test22'}],
.
.
[{'A': 'test33'},
{'A': 'test44'},
{'B': []}],
.
[{'A': 'test3'},
{'A': 'test4'},
{'B': [{'C': {'testabc': {'A': '111'}}},
{'C': {'test123': {'A': 'yyy'}, 'test456': {'A': '999abc'}}},
{'C': {'test123': {'A': 'yyy'}, 'test456': {'A': '999def'}}}]}]]
Now the output should be a nested list of dictionaries like:
desired_output = [[{'A': 'test1'}, {'A': 'test2'}, 'test456': {'A': '111def'}],
.
.
[{'A': 'test3'}, {'A': 'test4'}, 'test456': {'A': '999def'}]]
I am doing
for y in complex_data:
desired_output.append([y[2]['B'][2]['C'] for y in row] for row in y)
But this won't work. Varibale y doesn't iterate over list B. Can anyone please let me know what is the issue here and how to resolve it? i am using python3.9
Update: In some cases, the complete list B could be missing or could be empty {'B': []}.
Thanks in advance.
P.S: Please let me know if any info is missing or not clear.
Here the main idea is to convert dict to dataframe and dataframe to append on new list by rows
Code:
Step 1:
df = pd.json_normalize(complex_data )
df[2] = df[2].apply(lambda x: {k:v for k , v in dict(map(dict.popitem, x['B']))['C'].items() if k=='test456'})
df
#Output
0 1 2
0 {'A': 'test1'} {'A': 'test2'} {'test456': {'A': '111def'}}
1 {'A': 'test3'} {'A': 'test4'} {'test456': {'A': '999def'}}
Step 2:
desired_output = df.values.tolist()
desired_output
#output
[[{'A': 'test1'}, {'A': 'test2'}, {'test456': {'A': '111def'}}],
[{'A': 'test3'}, {'A': 'test4'}, {'test456': {'A': '999def'}}]]
Update you can avoid the None or {} value using if..else.. as below:
df[2].apply(lambda x: {} if len(x['B'])==0 else({} if not x['B'][-1] else ({'test456':x['B'][-1]['C']['test456']} if 'test456' in x['B'][-1]['C'].keys() else {})))
I have two lists
a = ['b','c','a','d','v']
g = [{'c':'1'},{'c':'2'},{'c':'3'},{'d':'1'},{'d':'2'}]
I want to match the key in the dictionary in the list g to the elements in list a, if they are matched, the elements in list g will be inserted into list a.
The desired outcome is:
['b','c',{'c':'1'},{'c':'2'},{'c':'3'},'a','d',{'d':'1'},{'d':'2'},'v']
Try:
a = ["b", "c", "a", "d", "v"]
g = [{"c": "1"}, {"c": "2"}, {"c": "3"}, {"d": "1"}, {"d": "2"}]
tmp = {}
for d in g:
for k in d:
tmp.setdefault(k, []).append(d)
out = []
for v in a:
out.append(v)
out.extend(tmp.get(v, []))
print(out)
Prints:
['b', 'c', {'c': '1'}, {'c': '2'}, {'c': '3'}, 'a', 'd', {'d': '1'}, {'d': '2'}, 'v']
Try using sorted:
print(sorted(a + g, key=lambda x: list(x)[0]))
Output:
['a', 'b', 'c', {'c': '1'}, {'c': '2'}, {'c': '3'}, 'd', {'d': '1'}, {'d': '2'}, 'e']
a = ['a','b','c','d','e']
g = [{'c':'1'},{'c':'2'},{'c':'3'},{'d':'1'},{'d':'2'},{'z':'1'}]
for dic in g:
for key in dic:
if key in a:
a.append(dic)
print(a)
#output ['a', 'b', 'c', 'd', 'e', {'c': '1'}, {'c': '2'}, {'c': '3'}, {'d': '1'}, {'d': '2'}]
After this, you can do sorting using lambda if required.
Consider the following list:
l=[[{'a': 'a'}, {'a': 'b'}, {'a': 1}], [{'a': 'a'}, {'a': 'b'}, {'a': 1}], [{'a': 'a'}, {'a': 'c'}, {'a': 1}]]
I would like to find the number of distinct elements on a same position in this list.
Example
if position=1, output would be 2 ( {'a': 'b'} and {'a': 'c'}).
if position=0, output would be 1: ( {'a': 'a'} and {'a': 'c'}).
Is there a way to do this using map/lambda ? I dont want to do a loop for this.
Thank you.
This would work:
len(set(map(lambda x: tuple(x[position].items()), l)))
Although I'd recommend never use such code IRL.
with a list like below that has one or more dicts
l = [{'b': 'h', 'c': (1,2)}, {'d': [0, 1], 'e': {'f': 2, 'g': 'i'} } ]
need to extract each key-value pair as an individual dict
Expected output
[{'b': 'h'}, {'c': (1,2)}, {'d': [0, 1]}, {'e': {'f': 2, 'g': 'i'} } ]
I have been trying to do this via list comprehension - the outer comprehension could be something like [ {k,v} for k, v in ?? - need some help in getting the inner comprehension.
I believe this is what you're looking for - except that the order of the elements might be different, but that's to be expected when dealing with dictionaries:
lst = [{'b': 'h', 'c': (1,2)}, {'d': [0, 1], 'e': {'f': 2, 'g': 'i'}}]
[{k: v} for d in lst for k, v in d.items()]
=> [{'c': (1, 2)}, {'b': 'h'}, {'e': {'g': 'i', 'f': 2}}, {'d': [0, 1]}]
This should work:
[{k: v} for i in l for k, v in i.items()]