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')
Related
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'}
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}]
I have some data that I have managed to put into a series in Python there are 369 elements in the series, within each element, there is a further two arrays containing starting x and y co-ordinates and ending x and y co-ordinates. I am looking to restructure this series in a simple data table with 369 entries and 4 columns.
First 10 Elements of the Series is
0 [{'y': 52, 'x': 50}, {'y': 44, 'x': 40}]
1 [{'y': 44, 'x': 40}, {'y': 75, 'x': 33}]
2 [{'y': 75, 'x': 33}, {'y': 76, 'x': 42}]
3 [{'y': 76, 'x': 42}, {'y': 36, 'x': 28}]
4 [{'y': 36, 'x': 28}, {'y': 12, 'x': 34}]
5 [{'y': 12, 'x': 34}, {'y': 30, 'x': 32}]
6 [{'y': 30, 'x': 32}, {'y': 70, 'x': 30}]
7 [{'y': 70, 'x': 30}, {'y': 35, 'x': 28}]
8 [{'y': 35, 'x': 28}, {'y': 23, 'x': 33}]
9 [{'y': 83, 'x': 46}, {'y': 87, 'x': 48}]
Name: list, dtype: object
By Using this, I can access the first element within that series, but ideally I want to be able to access each individual 'y' and 'x' value within these elements
passinglocations[1]
[{'y': 44, 'x': 40}, {'y': 75, 'x': 33}]
I cannot seem to find any further information in which I understand to get this in the usable form I want it
Any Insights?
Thanks
Assuming that your four columns are your y, x, y, x values, this should work:
passinglocations = [
[{'y': 44, 'x': 40}, {'y': 75, 'x': 33}],
[{'y': 23, 'x': 15}, {'y': 25, 'x': 37}]
]
def transform(passinglocations):
return [(loc[0]['y'], loc[0]['x'], loc[1]['y'], loc[1]['x']) for loc in passinglocations]
print(transform(passinglocations))
output:
[(44, 40, 75, 33), (23, 15, 25, 37)]
I have to insert a list of dictionaries having this syntax (I have more than 6500 dicts like these 3):
0: {208271891: {'bra': 'Solarmax',
'bri': 4,
'eur': 95.4,
'max': 1980,
'nam': '2000S',
'pan': {'bra': 'Sanyo',
'bri': 3,
'eff': 16,
'h': 861,
'hea': 50,
'mni': 1,
'mnm': 'free standing',
'n': 7,
'nam': 'HDE1 230',
'slo': 35,
't': -0.3,
'w': 1610,
'wp': 230},
'pha': 1,
'rat': 0.81,
'wp': 1610}},
1: {208271900: {'bra': 'Solarmax',
'bri': 4,
'eur': 95.4,
'max': 1980,
'nam': '2000S',
'pan': {'bra': 'Sanyo',
'bri': 3,
'eff': 16,
'h': 861,
'hea': -40,
'mni': 1,
'mnm': 'free standing',
'n': 9,
'nam': 'HDE1 230',
'slo': 30,
't': -0.3,
'w': 1610,
'wp': 230},
'pha': 1,
'rat': 1.05,
'wp': 2070}},
2: {208271892: {'bra': 'Solarmax',
'bri': 4,
'eur': 95.4,
'max': 1980,
'nam': '2000S',
'pan': {'bra': 'Sanyo',
'bri': 3,
'eff': 16,
'h': 861,
'hea': 50,
'mni': 1,
'mnm': 'free standing',
'n': 9,
'nam': 'HDE1 230',
'slo': 30,
't': -0.3,
'w': 1610,
'wp': 230},
'pha': 1,
'rat': 1.05,
'wp': 2070}}
I tried to delete keys with dict.pop() and 'del' but got this error: 'TypeError: 'int' object does not support item deletion'.
slMetadata = {}
for row in metadatas: #metadatas coming from mysql
mid = int(row['met_id'])
slMetadata.update(mid = mid)
bsInv = {
mid:
{
'wp' : wp,
'bra': str(row['invbraname']),
'bri': int(row['inm_bra_id']),
'nam': str(row['inm_name']),
'pha': int(row['inm_phases']),
'max': int(row['inm_maximal_power']),
'eur': float(row['inm_euro_efficiency']),
'pan':
{
'n' : int(row['inv_pan_numbers']),
'hea': int(row['inv_pan_heading']),
'slo': int(row['inv_pan_slope']),
'mni': int(row['inv_mnt_id']),
'mnm': str(row['mnt_name']),
'bra': str(row['panbraname']),
'bri': int(row['pan_bra_id']),
'nam': str(row['pan_name']),
'wp' : int(row['pan_wc']),
'eff': int(row['efficiency']),
't' : float(row['coefficient_p']),
'w' : int(row['pan_width']),
'h' : int(row['pan_height'])
}
}
}
i = 0
dictToInsert = {}
for dic in slMetadata:
dictToInsert[i] = slMetadata[dic]
i += 1
if len(dictToInsert) > 0:
insertion = dbCollection.insert_many(dictToInsert)
What I want is to insert all these dicts into mongoDb but I have the error below : bson.errors.InvalidDocument: documents must have only string keys, key was 0.
Which I fully understand and know that I can't insert into mongoDb with 'int' key. But what is the alternative?
Thanks.
Try
dictToInsert[str(i)] = slMetadata[dic]
instead of
dictToInsert[i] = slMetadata[dic]
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}]