Combine elements by the key in list - python

I have the following list
some_list = [{'key': 'YOUNG', 'x': 22, 'y': 0.9},
{'key': 'OLD', 'x': 45, 'y': 0.6},
{'key': 'OLD', 'x': 40, 'y': 0.3},
{'key': 'YOUNG', 'x': 25, 'y': 0.3}]
and I would like to change it to:
[{'key': 'YOUNG', 'values': [ {'x': 25, 'y': 0.3}, {'x': 22, 'y': 0.9} ]}
{'key': 'OLD', 'values': [ {'x': 40, 'y': 0.3}, {'x': 45, 'y': 0.6} ]}]
Added some of my attempts
arr = [{'key': 'YOUNG', 'x': 22, 'y': 0.9},
{'key': 'OLD', 'x': 45, 'y': 0.6},
{'key': 'OLD', 'x': 40, 'y': 0.3},
{'key': 'YOUNG', 'x': 25, 'y': 0.3}]
all_keys = []
for item in arr:
all_keys.append(item['key'])
all_keys = list(set(all_keys))
res = [[{
'key': key,
'values': {'x': each['x'], 'y': each['y']}
} for each in arr if each['key'] == key]
for key in all_keys]
print res
But the result is not right, it constructs more lists:
[[{'values': {'y': 0.6, 'x': 45}, 'key': 'OLD'}, {'values': {'y': 0.3, 'x': 40}, 'key': 'OLD'}], [{'values': {'y': 0.9, 'x': 22}, 'key': 'YOUNG'}, {'values': {'y': 0.3, 'x': 25}, 'key': 'YOUNG'}]]
Thanks.

The loops should be like this:
res = [{ 'key': key,
'values': [{'x': each['x'], 'y': each['y']}
for each in arr if each['key'] == key] }
for key in all_keys]

Using an intermediate dictionary you can do:
>>> temp_data = {}
>>> for x in some_list:
... temp_data.setdefault(x['key'], []).append({k: x[k] for k in ['x', 'y']})
>>> [{'key': k, 'values': v} for k,v in temp_data.items()]
[{'key': 'OLD', 'values': [{'x': 45, 'y': 0.6}, {'x': 40, 'y': 0.3}]},
{'key': 'YOUNG', 'values': [{'x': 22, 'y': 0.9}, {'x': 25, 'y': 0.3}]}]
Though personally I would just leave it in dictionary form:
>>> temp_data
{'OLD': [{'x': 45, 'y': 0.6}, {'x': 40, 'y': 0.3}],
'YOUNG': [{'x': 22, 'y': 0.9}, {'x': 25, 'y': 0.3}]}

from itertools import *
data = [{'key': 'YOUNG', 'x': 22, 'y': 0.9},
{'key': 'OLD', 'x': 45, 'y': 0.6},
{'key': 'OLD', 'x': 40, 'y': 0.3},
{'key': 'YOUNG', 'x': 25, 'y': 0.3}]
data = sorted(data, key=lambda x: x['key'])
groups = []
uniquekeys = []
for k, v in groupby(data, lambda x: x['key'] ):
val_list = []
for each_val in v:
val_list.append({ 'x' : each_val['x'], 'y': each_val['y']})
groups.append(val_list)
uniquekeys.append(k)
print uniquekeys
print groups
print zip(uniquekeys, groups)
You will get your output as a list of tuples where the first element is your key and the second one is the group/list of values,
[('OLD', [{'y': 0.6, 'x': 45}, {'y': 0.3, 'x': 40}]), ('YOUNG', [{'y': 0.9, 'x': 22}, {'y': 0.3, 'x': 25}])]

some_list = [{'key': 'YOUNG', 'x': 22, 'y': 0.9},
{'key': 'OLD', 'x': 45, 'y': 0.6},
{'key': 'OLD', 'x': 40, 'y': 0.3},
{'key': 'YOUNG', 'x': 25, 'y': 0.3}]
outDict = {}
for dictionary in some_list:
key = dictionary['key']
copyDict = dictionary.copy() #This leaves the original dict list unaltered
del copyDict['key']
if key in outDict:
outDict[key].append(copyDict)
else:
outDict[key] = [copyDict]
print(outDict)
print(some_list)

Here you go-
some_list = [{'key': 'YOUNG', 'x': 22, 'y': 0.9},
{'key': 'OLD', 'x': 45, 'y': 0.6},
{'key': 'OLD', 'x': 40, 'y': 0.3},
{'key': 'YOUNG', 'x': 25, 'y': 0.3}]
dict_young_vals = []
dict_old_vals = []
for dict_step in some_list:
temp_dict = {}
if (dict_step['key'] == 'YOUNG'):
for keys in dict_step.keys():
if keys != 'key':
temp_dict[keys] = dict_step[keys]
if temp_dict != {}:
dict_young_vals.append(temp_dict)
if (dict_step['key'] == 'OLD'):
for keys in dict_step.keys():
if keys != 'key':
temp_dict[keys] = dict_step[keys]
if temp_dict != {}:
dict_old_vals.append(temp_dict)
dict_young = {'key':'YOUNG'}
dict_young['values'] = dict_young_vals
dict_old = {'key': 'OLD'}
dict_old['values'] = dict_old_vals
print(dict_young_vals)
result_dict = []
result_dict.append(dict_young)
result_dict.append(dict_old)
print(result_dict)

Another try may be using defaultdict- It will run faster if data is larger.
from collections import defaultdict
data = defaultdict(list)
some_list = [{'key': 'YOUNG', 'x': 22, 'y': 0.9},
{'key': 'OLD', 'x': 45, 'y': 0.6},
{'key': 'OLD', 'x': 40, 'y': 0.3},
{'key': 'YOUNG', 'x': 25, 'y': 0.3}]
for item in some_list:
vals = item.copy()
del vals['key']
data[item['key']].append(vals)
print [{'key':k,'values':v} for k,v in data.items()]
Output (dictionary does not care about ordering)-
[{'values': [{'y': 0.6, 'x': 45}, {'y': 0.3, 'x': 40}], 'key': 'OLD'}, {'values': [{'y': 0.9, 'x': 22}, {'y': 0.3, 'x': 25}], 'key': 'YOUNG'}]

some_list = [{'key': 'YOUNG', 'x': 22, 'y': 0.9},
{'key': 'OLD', 'x': 45, 'y': 0.6},
{'key': 'OLD', 'x': 40, 'y': 0.3},
{'key': 'YOUNG', 'x': 25, 'y': 0.3}]
x=[]
for i in some_list:
d={}
d["key"]=i["key"]
d["values"]=[{m:n for m,n in i.items() if m!="key"}]
if d["key"] not in [j["key"] for j in x]:
x.append(d)
else:
for k in x:
if k["key"]==d["key"]:
k["values"].append(d["values"][0])
print x
Output:[{'values': [{'y': 0.9, 'x': 22}, {'y': 0.3, 'x': 25}], 'key': 'YOUNG'}, {'values': [{'y': 0.6, 'x': 45}, {'y': 0.3, 'x': 40}], 'key': 'OLD'}]

Related

is there any way in python to create list using key value pairs

how to create a list of key value pairs in python???
I have these two lists:
x = [1,2,3,4,5]
y = [11,12,13,14,15]
I have tried this code:
l = {i:{'x': x[i], 'y': y[i]} for i in range(len(x))}
print(l)
output I am getting:
{0: {'x': 1, 'y': 11}, 1: {'x': 2, 'y': 12}, 2: {'x': 3, 'y': 13}, 3: {'x': 4, 'y': 14}, 4: {'x': 5, 'y': 15}}
expected output:
[0: {'x': 1, 'y': 11}, 1: {'x': 2, 'y': 12}, 2: {'x': 3, 'y': 13}, 3: {'x': 4, 'y': 14}, 4: {'x': 5, 'y': 15}]
Maybe you need this
x = [1,2,3,4,5]
y = [11,12,13,14,15]
l = [{i:{'x': x[i], 'y': y[i]}}for i in range(len(x))]
print(l)
The closest you can get to the expected output is an array which contains dictionaries it would look like this.
x = [1,2,3,4,5]
y = [11,12,13,14,15]
array = []
for i in len(x):
array.append({'x' : x[i], 'y' : y[i]})
Output will be:
[{'x': 1, 'y': 11}, {'x': 2, 'y': 12}]
You can access an element like this:
array[0]['x'] = 1
array[1]['y'] = 12

How to access integer value from a list [duplicate]

This question already has answers here:
Getting a list of values from a list of dicts
(10 answers)
Closed 3 years ago.
result = [{'label': 'butterfly', 'confidence': 0.16034618, 'topleft': {'x': 195, 'y': 23}, 'bottomright': {'x': 220, 'y': 45}}, {'label': 'butterfly', 'confidence': 0.27062774, 'topleft': {'x': 64, 'y': 58}, 'bottomright': {'x': 98, 'y': 85}}, {'label': 'butterfly', 'confidence': 0.114007816, 'topleft': {'x': 247, 'y': 191}, 'bottomright': {'x': 268, 'y': 211}}]
I want to return only the confidence value from each element.
Try this:
my_list = [
{
'label': 'butterfly',
'confidence': 0.16034618,
'topleft': {'x': 195, 'y': 23},
'bottomright': {'x': 220, 'y': 45}
},
{
'label': 'butterfly',
'confidence': 0.27062774,
'topleft': {'x': 64, 'y': 58},
'bottomright': {'x': 98, 'y': 85}
}
]
confidence_values = list(
map(
lambda x: x['confidence'],
my_list
)
)
print(confidence_values)

How check if values of keys in list of dictionaries are both equal 0

I have a list of dictionaries like:
dicts = [dict1,dict2,dict3,dict4]
dict1 = [{'name': 'blue', 'y': 1}, {'something else': 'red', 'y': 0}]
dict2 = [{'name': 'green', 'y': 0}, {'name': 'purple', 'y':2}]
dicts are list of dictionaries
How can I check if both values in dict1 first and second y value is 0 etc.
If dict have both y == 0 then assign empty array
I have tried also something like this but have to repeat this so many times for each dict
check = 0
for el in dict1:
if el['y'] == 0:
check += 1
if check == len(dict1):
dict1 = []
for el in dicts:
for y in el:
if all(x == 0 for x in y.values()):
el = []
You need something like this.
dicts=[]
new_dicts=[]
for dic in dicts:
flag=0
for el in dic:
if el['y']!=0:
flag=1
break
if flag==0:
new_dict.append([])
else:
new_dict.append(dic)
If a one-line solution is too complex, split up the task and enumerate your dicts to replace the element you checked to have all {"y":0}:
dict1 = [{'name': 'blue', 'y': 1}, {'something else': 'red', 'y': 0}]
dict2 = [{'name': 'green', 'y': 0}, {'name': 'purple', 'y':2}]
dict3 = [{'name': 'green', 'y': 0}, {'name': 'purple', 'y':0}]
dict4 = [{'name': 'green', 'y': 0}, {'name': 'purple', 'y':2}]
dicts = [dict1,dict2,dict3,dict4]
for i,d in enumerate(dicts):
zeros = all(i["y"]== 0 for i in d) # check if all are 0
if zeros:
dicts[i] = [] # if so replace element in dicts by []
print (dicts)
Outputs:
[[{'name': 'blue', 'y': 1}, {'something else': 'red', 'y': 0}],
[{'name': 'green', 'y': 0}, {'name': 'purple', 'y': 2}],
[],
[{'name': 'green', 'y': 0}, {'name': 'purple', 'y': 2}]]
[[] if all([i['y']==0 for i in item]) else item for item in dicts]
Take example
dict1 = [{'name': 'blue', 'y': 1}, {'something else': 'red', 'y': 0}]
dict2 = [{'name': 'green', 'y': 0}, {'name': 'purple', 'y':2}]
dict3 = [{'name': 'green', 'y': 0}, {'name': 'purple', 'y':0}]
dict4 = [{'name': 'green', 'y': 0}, {'name': 'purple', 'y':2}]
dicts = [dict1,dict2,dict3,dict4]
The output would be
[[{'name': 'blue', 'y': 1}, {'something else': 'red', 'y': 0}],
[{'name': 'green', 'y': 0}, {'name': 'purple', 'y': 2}],
[],
[{'name': 'green', 'y': 0}, {'name': 'purple', 'y': 2}]]

Grouping by key value property in List of dict python

I have orig list of tuples that comprises dict & text values.
orig = [({'x': 28.346, 'y': 19},'Text0'),
({'x': 109.726, 'y': 19},'Text1'),
({'x': 147.776, 'y': 19},'Text2'),
({'x': 153.606, 'y': 24}, 'Text3'),
({'x': 452.788, 'y': 24}, 'Text4'),
({'x': 504.168, 'y': 34}, 'Text5'),
({'x': 527.768, 'y': 34}, 'Text6'),
({'x': 533.598, 'y': 45},'Text7'),
({'x': 64.291, 'y': 55},'Text8'),
({'x': 98.623, 'y': 55},'Text9')]
and I want to filter group from the key='y' in the which would give me list it according to unique values in y. Something like following:
res = [
[({'x': 28.346, 'y': 19},'Text0'),
({'x': 109.726, 'y': 19},'Text1'),
({'x': 147.776, 'y': 19},'Text2')],
[({'x': 153.606, 'y': 24}, 'Text3'),
({'x': 452.788, 'y': 24}, 'Text4')],
[({'x': 504.168, 'y': 34}, 'Text5'),
({'x': 527.768, 'y': 34}, 'Text6')],
[({'x': 533.598, 'y': 45},'Text7')],
[({'x': 64.291, 'y': 55},'Text8'),
({'x': 98.623, 'y': 55},'Text9')]]
If you use numpy it will be bit easier.
import numpy as np
orig = [({'x': 28.346, 'y': 19}, 'Text0'),
({'x': 109.726, 'y': 19}, 'Text1'),
({'x': 147.776, 'y': 19}, 'Text2'),
({'x': 153.606, 'y': 24}, 'Text3'),
({'x': 452.788, 'y': 24}, 'Text4'),
({'x': 504.168, 'y': 34}, 'Text5'),
({'x': 527.768, 'y': 34}, 'Text6'),
({'x': 533.598, 'y': 45}, 'Text7'),
({'x': 64.291, 'y': 55}, 'Text8'),
({'x': 98.623, 'y': 55}, 'Text9')]
input_array = np.array([val[0]['y'] for val in orig])
out_array = [np.where(input_array == element)[0].tolist() for element in np.unique(input_array)]
res = [[orig[i] for i in ind_arr] for ind_arr in out_array]
print(res)
Output:
[[({'x': 28.346, 'y': 19}, 'Text0'),
({'x': 109.726, 'y': 19}, 'Text1'),
({'x': 147.776, 'y': 19}, 'Text2')],
[({'x': 153.606, 'y': 24}, 'Text3'),
({'x': 452.788, 'y': 24}, 'Text4')],
[({'x': 504.168, 'y': 34}, 'Text5'),
({'x': 527.768, 'y': 34}, 'Text6')],
[({'x': 533.598, 'y': 45}, 'Text7')],
[({'x': 64.291, 'y': 55}, 'Text8'),
({'x': 98.623, 'y': 55}, 'Text9')]]
A two-liner solution using itertools.groupby and list comprehension:
from itertools import groupby
# group by the input orig with a key of dict "y" and then take it in a list of list comprehension
print ([[x for x in v] for k, v in groupby(orig, key= lambda x: x[0]["y"])])
Result:
[[({'x': 28.346, 'y': 19}, 'Text0'), ({'x': 109.726, 'y': 19}, 'Text1'), ({'x': 147.776, 'y': 19}, 'Text2')], [({'x': 153.606, 'y': 24}, 'Text3'), ({'x': 452.788, 'y': 24}, 'Text4')], [({'x': 504.168, 'y': 34}, 'Text5'), ({'x': 527.768, 'y': 34}, 'Text6')], [({'x': 533.598, 'y': 45}, 'Text7')], [({'x': 64.291, 'y': 55}, 'Text8'), ({'x': 98.623, 'y': 55}, 'Text9')]]
I hope this counts :)

Groupby and sort the values in dict in Python

I have a dictionary as follows in python and I have to group by 'label' and get the highest value of 'confidence' for each 'label'
[{'label': 'id',
'confidence': 0.11110526,
'topleft': {'x': 0, 'y': 0},
'bottomright': {'x': 187, 'y': 57}},
{'label': 'id',
'confidence': 0.10690566,
'topleft': {'x': 265, 'y': 0},
'bottomright': {'x': 525, 'y': 54}},
{'label': 'name',
'confidence': 0.15541315,
'topleft': {'x': 9, 'y': 24},
'bottomright': {'x': 116, 'y': 58}},
{'label': 'group',
'confidence': 0.12578075,
'topleft': {'x': 53, 'y': 24},
'bottomright': {'x': 153, 'y': 61}},
{'label': 'name',
'confidence': 0.12709439,
'topleft': {'x': 0, 'y': 0},
'bottomright': {'x': 247, 'y': 84}},
{'label': 'group',
'confidence': 0.116156094,
'topleft': {'x': 96, 'y': 23},
'bottomright': {'x': 191, 'y': 61}}]
How do I achieve this efficiently
You can do this with groupby
for n,g in groupby(tst,key=lambda x:x['label']):
print n,max(list(g),key=lambda x:x['confidence']).get('confidence')
Result:
id 0.11110526
name 0.15541315
group 0.12578075
name 0.12709439
group 0.116156094

Categories