Get all first items of any unknown content in dict - python

I have nested dictionary like this one:
results={
0: {'id': 87535653, 'cc': 0, 'cover': 89, 'grid': 'VQ'},
1: {'id': 31213450, 'cc': 0, 'cover': 99, 'grid': 'VQ'},
2: {'id': 22343446, 'cc': 0.1, 'cover': 79, 'grid': 'VP'},
3: {'id': 34568756, 'cc': 0, 'cover': 34, 'grid': 'VQ'},
4: {'id': 43532251, 'cc': 0.2, 'cover': 78, 'grid': 'DS'},
5: {'id': 42532376, 'cc': 23, 'cover': 90, 'grid': 'ZF'},
}
What I want is to get only the first item of any content in grid. So, for this example I want to get back this:
results={
0: {'id': 87535653, 'cc': 0, 'cover': 89, 'grid': 'VQ'},
2: {'id': 22343446, 'cc': 0.1, 'cover': 79, 'grid': 'VP'},
4: {'id': 43532251, 'cc': 0.2, 'cover': 78, 'grid': 'DS'},
5: {'id': 42532376, 'cc': 23, 'cover': 90, 'grid': 'ZF'},
}
The challenge: I don't know the content in Grid before. That is, anything can be in there and I can't iterate according to the specific content. The code has to recognize independently that this is an item that does not yet exist with this content.
How can I iterate over the files to get the result I want?

You can iterate over the dict and mark each grid you found, that way the next time you find it you dont add it to the final dict
In [1]: results={
...: 0: {'id': 87535653, 'cc': 0, 'cover': 89, 'grid': 'VQ'},
...: 1: {'id': 31213450, 'cc': 0, 'cover': 99, 'grid': 'VQ'},
...: 2: {'id': 22343446, 'cc': 0.1, 'cover': 79, 'grid': 'VP'},
...: 3: {'id': 34568756, 'cc': 0, 'cover': 34, 'grid': 'VQ'},
...: 4: {'id': 43532251, 'cc': 0.2, 'cover': 78, 'grid': 'DS'},
...: 5: {'id': 42532376, 'cc': 23, 'cover': 90, 'grid': 'ZF'},
...: }
In [2]: final_dict = {}
In [3]: _collected_grids = set()
In [4]: for key, value in results.items():
...: if value['grid'] not in _collected_grids:
...: final_dict[key] = value
...: _collected_grids.add(value['grid'])
...:
In [5]: final_dict
Out[5]:
{0: {'id': 87535653, 'cc': 0, 'cover': 89, 'grid': 'VQ'},
2: {'id': 22343446, 'cc': 0.1, 'cover': 79, 'grid': 'VP'},
4: {'id': 43532251, 'cc': 0.2, 'cover': 78, 'grid': 'DS'},
5: {'id': 42532376, 'cc': 23, 'cover': 90, 'grid': 'ZF'}}

You can do it with Pandas:
import pandas as pd
df=pd.DataFrame.from_dict(results, orient='index')
df=df.drop_duplicates('grid')
res = df.to_dict(orient='index')
>>>print(res)
{0: {'id': 87535653, 'cc': 0.0, 'cover': 89, 'grid': 'VQ'},
2: {'id': 22343446, 'cc': 0.1, 'cover': 79, 'grid': 'VP'},
4: {'id': 43532251, 'cc': 0.2, 'cover': 78, 'grid': 'DS'},
5: {'id': 42532376, 'cc': 23.0, 'cover': 90, 'grid': 'ZF'}}

See below (the idea is to keep a "note" of the grid data you already scanned)
results = {
0: {'id': 87535653, 'cc': 0, 'cover': 89, 'grid': 'VQ'},
1: {'id': 31213450, 'cc': 0, 'cover': 99, 'grid': 'VQ'},
2: {'id': 22343446, 'cc': 0.1, 'cover': 79, 'grid': 'VP'},
3: {'id': 34568756, 'cc': 0, 'cover': 34, 'grid': 'VQ'},
4: {'id': 43532251, 'cc': 0.2, 'cover': 78, 'grid': 'DS'},
5: {'id': 42532376, 'cc': 23, 'cover': 90, 'grid': 'ZF'},
}
grids = set()
data = dict()
for k, v in results.items():
if v['grid'] not in grids:
data[k] = v
grids.add(v['grid'])
for k, v in data.items():
print(f'{k} {v}')
output
0 {'id': 87535653, 'cc': 0, 'cover': 89, 'grid': 'VQ'}
2 {'id': 22343446, 'cc': 0.1, 'cover': 79, 'grid': 'VP'}
4 {'id': 43532251, 'cc': 0.2, 'cover': 78, 'grid': 'DS'}
5 {'id': 42532376, 'cc': 23, 'cover': 90, 'grid': 'ZF'}

Related

Nested dictionary from a txt with the dictionary

I have a txt file with the dictionary like this:
{'origin': {'Ukraine': 50, 'Portugal': 20, 'others': 10}, 'native language': {'ucranian': 50; 'english': 45, 'russian': 30, 'others': 10}, 'second language': {'ucranian': 50; 'english': 45, 'russian': 30, 'others': 10, 'none': 0}, 'profession': {'medical doctor': 50, 'healthcare professional': 40, 'cooker': 30, 'others': 10, 'spy': 0}, 'first aid skills': {'yes': 50, 'no': 0}, 'driving skills': {'yes': 40, 'no': 0}, 'cooking skills': {'yes': 50, 'some': 30, 'no': 0}, 'IT skills': {'yes': 50, 'little': 35, 'no': 0}}
And I want to create a dictionary from this
I tried using ast.literal_eval but it gives me the following error:
SyntaxError: expression expected after dictionary key and ':'
This is my code :
def helpersSkills(helpersFile, skillsFile):
"""
"""
helpers = open(helpersFile, 'r')
skills = open(skillsFile, 'r')
skillsLines = skills.read()
dictionary = ast.literal_eval(skillsLines)
...
helpersSkills('helpersArrived2.txt', 'skills.txt')
as said by #ThierryLathuille it was just some writing errors in the txt file
so its working:
{'origin': {'Ukraine': 50, 'Portugal': 20, 'others': 10}, 'native language': {'ucranian': 50, 'english': 45, 'russian': 30, 'others': 10}, 'second language': {'ucranian': 50, 'english': 45, 'russian': 30, 'others': 10, 'none': 0}, 'profession': {'medical doctor': 50, 'healthcare professional': 40, 'cooker': 30, 'others': 10, 'spy': 0}, 'first aid skills': {'yes': 50, 'no': 0}, 'driving skills': {'yes': 40, 'no': 0}, 'cooking skills': {'yes': 50, 'some': 30, 'no': 0}, 'IT skills': {'yes': 50, 'little': 35, 'no': 0}}
This is the code :
def helpersSkills(helpersFile, skillsFile):
"""
"""
helpers = open(helpersFile, 'r')
skills = open(skillsFile, 'r')
skillsLines = skills.read()
dictionary = ast.literal_eval(skillsLines)
...
helpersSkills('helpersArrived2.txt', 'skills.txt')

How to append the sum of keys of each dictionary to another key?

I have a json format like below:-
l = {'itc': 'ball','classes': [{'scores': [{'len': 89,'width':50},{'len': 27,'width': 17}]},
{'scores': [{'len': 90,'width': 44},{'len': 0,'width': 0}]},
{'scores': [{'len': 50,'width': 26},{'len': 0,'width': 0}]}]}
Now I want to create a new list of dictionaries. like below:-
output= [{'result': [{'len': 89, 'width': 50}, {'len': 27, 'width': 17}], 'total': 116}, {'result': [{'len': 90, 'width': 44}, {'len': 0, 'width': 0}], 'total': 90}, {'result': [{'len': 50, 'width': 26}, {'len': 0, 'width': 0}], 'total': 50}]
I was able to divide the values and was able to place in the required format but I am not able to append the total score key 'len' of every dictionary in to the total of every dictionary result. It is calculating the whole values of all the dictionaries. The code and the output I got is as follows:-
added=[]
output=[]
for k,v in l.items():
if k=='classes':
for i in v:
for ke,ve in i.items():
if ke=='scores':
for j in ve:
for key,val in j.items():
if key=='len':
add = val
added.append(add)
sumed=sum(added)
out={'result':ve,'total':sumed}
output.append(out)
print(output)
Output I got:-
[{'result': [{'len': 89, 'width': 50}, {'len': 27, 'width': 17}], 'total': 116}, {'result': [{'len': 90, 'width': 44}, {'len': 0, 'width': 0}], 'total': 206}, {'result': [{'len': 50, 'width': 26}, {'len': 0, 'width': 0}], 'total': 256}]
As you could see that its summing up all the values and appending them to key total. How do I append sum of each dictionary score to the total key of each dictionary result as below?
output= [{'result': [{'len': 89, 'width': 50}, {'len': 27, 'width': 17}], 'total': 116}, {'result': [{'len': 90, 'width': 44}, {'len': 0, 'width': 0}], 'total': 90}, {'result': [{'len': 50, 'width': 26}, {'len': 0, 'width': 0}], 'total': 50}]
Use sum to get the total:
res = [{"result" : cl["scores"], "total" : sum(d["len"] for d in cl["scores"])} for cl in l["classes"]]
print(res)
Output
[{'result': [{'len': 89, 'width': 50}, {'len': 27, 'width': 17}], 'total': 116}, {'result': [{'len': 90, 'width': 44}, {'len': 0, 'width': 0}], 'total': 90}, {'result': [{'len': 50, 'width': 26}, {'len': 0, 'width': 0}], 'total': 50}]
Or the equivalent, for-loop:
res = []
for cl in l["classes"]:
scores = cl["scores"]
total = sum(d["len"] for d in cl["scores"])
res.append({"result": scores, "total": total})

Compare list of dictionaries with variable number of dictionaries in each list

I have two lists of dictionaries as:
list1 = [
{'vehicle': 1, 'mileage': 25, 'speed': 80},
{'vehicle': 2, 'mileage': 35, 'speed': 70},
{'vehicle': 3, 'mileage': 40, 'speed': 90},
{'vehicle': 5, 'mileage': 40, 'speed': 90}
]
list2 = [
{'vehicle': 1, 'mileage': 35, 'speed': 80},
{'vehicle': 2, 'mileage': 35, 'speed': 70},
{'vehicle': 3, 'mileage': 40, 'speed': 80},
{'vehicle': 4, 'mileage': 40, 'speed': 80}
]
I have to print dictionaries from list1 if vechiles of same name is on list2 and mileage and speed of corresponding vehilce is greater than or equal to that of in list2.
In this example, output should be:
[{'vehicle': 1, 'mileage': 25, 'speed': 80},
{'vehicle': 2, 'mileage': 35, 'speed': 70}]
Any help is highly appreciated.
You could do create a lookup dictionary to search for the corresponding matches in O(1):
list1 = [{'vehicle': 1, 'mileage': 25, 'speed': 80},
{'vehicle': 2, 'mileage': 35, 'speed': 70},
{'vehicle': 3, 'mileage': 40, 'speed': 90},
{'vehicle': 5, 'mileage': 40, 'speed': 90}]
list2 = [{'vehicle': 1, 'mileage': 35, 'speed': 80},
{'vehicle': 2, 'mileage': 35, 'speed': 70},
{'vehicle': 3, 'mileage': 40, 'speed': 80},
{'vehicle': 4, 'mileage': 40, 'speed': 80}]
lookup = {e['vehicle'] : e for e in list1 }
result = []
for e in list2 :
if e['vehicle'] in lookup:
d = lookup[e['vehicle']]
if e['mileage'] >= d['mileage'] and e['speed'] >= d['speed']:
result.append(d)
print(result)
Output
[{'vehicle': 1, 'mileage': 25, 'speed': 80}, {'vehicle': 2, 'mileage': 35, 'speed': 70}]
An alternative using a list comprehension:
def better(e, d, keys=('mileage', 'speed')):
return all(e[k] >= d[k] for k in keys)
result = [lookup[e['vehicle']] for e in list2 if e['vehicle'] in lookup and better(e, lookup[e['vehicle']])]
print(result)
The overall complexity of both approaches is O(n).
I would use pandas Dataframe.
Not the most effecient but very readable
import pandas as pd
df1 = pd.DataFrame(list1)
df2 = pd.DataFrame(list2)
result_df = df1[(df1.vehicle.isin(df2.vehicle)) & (df1.speed <= df2.speed) & (df1.mileage <= df2.mileage)]
result_list = result_df.to_dict('records')
print(result_list)
output:
[{'mileage': 25, 'speed': 80, 'vehicle': 1},
{'mileage': 35, 'speed': 70, 'vehicle': 2}]
You could convert your list of dicts to nested dicts, where vehicle is the key:
list1 = [
{"vehicle": 1, "mileage": 25, "speed": 80},
{"vehicle": 2, "mileage": 35, "speed": 70},
{"vehicle": 3, "mileage": 40, "speed": 90},
{"vehicle": 5, "mileage": 40, "speed": 90},
]
list2 = [
{"vehicle": 1, "mileage": 35, "speed": 80},
{"vehicle": 2, "mileage": 35, "speed": 70},
{"vehicle": 3, "mileage": 40, "speed": 80},
{"vehicle": 4, "mileage": 40, "speed": 80},
]
dict1 = {x["vehicle"]: x for x in list1}
# {1: {'vehicle': 1, 'mileage': 25, 'speed': 80}, 2: {'vehicle': 2, 'mileage': 35, 'speed': 70}, 3: {'vehicle': 3, 'mileage': 40, 'speed': 90}, 5: {'vehicle': 5, 'mileage': 40, 'speed': 90}}
dict2 = {x["vehicle"]: x for x in list2}
# {1: {'vehicle': 1, 'mileage': 35, 'speed': 80}, 2: {'vehicle': 2, 'mileage': 35, 'speed': 70}, 3: {'vehicle': 3, 'mileage': 40, 'speed': 80}, 4: {'vehicle': 4, 'mileage': 40, 'speed': 80}}
Then take the intersection of keys and return the result as a list of dicts using a list comprehension:
result = [
dict1[k]
for k in dict1.keys() & dict2.keys()
if dict2[k]["mileage"] >= dict1[k]["mileage"]
and dict2[k]["speed"] >= dict1[k]["speed"]
]
print(result)
Output:
[{'vehicle': 1, 'mileage': 25, 'speed': 80}, {'vehicle': 2, 'mileage': 35, 'speed': 70}]

How can i add the dictionary into list using append function or the other function?

Execusme, i need your help!
Code Script
tracks_ = []
track = {}
if category == 'reference':
for i in range(len(tracks)):
if len(tracks) >= 1:
_tracks = tracks[i]
track['id'] = _track['id']
tracks_.append(track)
print (tracks_)
tracks File
[{'id': 345, 'mode': 'ghost', 'missed': 27, 'box': [0.493, 0.779, 0.595, 0.808], 'score': 89, 'class': 1, 'time': 3352}, {'id': 347, 'mode': 'ghost', 'missed': 9, 'box': [0.508, 0.957, 0.631, 0.996], 'score': 89, 'class': 1, 'time': 5463}, {'id': 914, 'mode': 'track', 'missed': 0, 'box': [0.699, 0.496, 0.991, 0.581], 'score': 87, 'class': 62, 'time': 6549}, {'id': 153, 'mode': 'track', 'missed': 0, 'box': [0.613, 0.599, 0.88, 0.689], 'score': 73, 'class': 62, 'time': 6549}, {'id': 588, 'mode': 'track', 'missed': 0, 'box': [0.651, 0.685, 0.958, 0.775], 'score': 79, 'class': 62, 'time': 6549}, {'id': 972, 'mode': 'track', 'missed': 0, 'box': [0.632, 0.04, 0.919, 0.126], 'score': 89, 'class': 62, 'time': 6549}, {'id': 300, 'mode': 'ghost', 'missed': 6, 'box': [0.591, 0.457, 0.74, 0.498], 'score': 71, 'class': 62, 'time': 5716}]
Based on the codescript and the input above, i want to print out the tracks_ and the result is
[{'id': 300}, {'id': 300}, {'id': 300}, {'id': 300}, {'id': 300}, {'id': 300}, {'id': 300}]
but, the result that print out should be like this :
[{'id': 345}, {'id': 347},{'id': 914}, {'id': 153}, {'id': 588}, {'id': 972}, {'id': 300}, ]
you are appending to your list track_ the same dict , which causes to have in your list only references of the same dict, practically you have only one dict in your list tracks_, and any modification to the dict track will be reflected in all the elements of your list, to fix you should create a new dict on each iteration:
if category == 'reference' and len(tracks) >= 1:
for d in tracks:
tracks_.append({'id' : d['id']})
you could use a list comprehension:
tracks_ = [{'id': t['id']} for t in tracks]
tracks_
output:
[{'id': 345},
{'id': 347},
{'id': 914},
{'id': 153},
{'id': 588},
{'id': 972},
{'id': 300}]

Couldn't rename field in python list (key, value structure)

I have below list with nested lists (sort of key,values)
inp1=[{'id': 0, 'name': 98, 'value': 9}, {'id': 1, 'name': 66, 'value': 8}, {'id': 2, 'name': 29, 'value': 5}, {'id': 3, 'name': 99, 'value': 3}, {'id': 4, 'name': 15, 'value': 9}]
Am trying to replace 'name' with 'wid' and 'value' with 'wrt', how can I do it on same list?
My output should be like
inp1=[{'id': 0, 'wid': 98, 'wrt': 9}, {'id': 1, 'wid': 66, 'wrt': 8}, {'id': 2, 'wid': 29, 'wrt': 5}, {'id': 3, 'wid': 99, 'wrt': 3}, {'id': 4, 'wid': 15, 'wrt': 9}]
I tried below, but it doesn't work as list cannot be indexed with string but integer
inp1['name'] = inp1['wid']
inp1['value'] = inp1['wrt']
I tried if I can find any examples, but mostly I found only this for dictionary and not list.
You need to iterate each item, and remove the old entry (dict.pop is handy for this - it removes an entry and return the value) and assign to new keyes:
>>> inp1 = [
... {'id': 0, 'name': 98, 'value': 9},
... {'id': 1, 'name': 66, 'value': 8},
... {'id': 2, 'name': 29, 'value': 5},
... {'id': 3, 'name': 99, 'value': 3},
... {'id': 4, 'name': 15, 'value': 9}
... ]
>>>
>>> for d in inp1:
... d['wid'] = d.pop('name')
... d['wrt'] = d.pop('value')
...
>>> inp1
[{'wid': 98, 'id': 0, 'wrt': 9},
{'wid': 66, 'id': 1, 'wrt': 8},
{'wid': 29, 'id': 2, 'wrt': 5},
{'wid': 99, 'id': 3, 'wrt': 3},
{'wid': 15, 'id': 4, 'wrt': 9}]
def f(item):
if(item.has_key('name') and not item.has_key('wid')):
item['wid']=item.pop('name')
if(item.has_key('value') and not item.has_key('wrt')):
item['wrt']=item.pop('value')
map(f,inp1)
Output:
[{'wrt': 9, 'wid': 98, 'id': 0}, {'wrt': 8, 'wid': 66, 'id': 1}, {'wrt': 5, 'wid': 29, 'id': 2}, {'wrt': 3, 'wid': 99, 'id': 3}, {'wrt': 9, 'wid': 15, 'id': 4}]

Categories

Resources