I am trying to lowercase all the keys in a dictionary(s) that are within a list. I actually have a code that prints the lowercase output I want within a for loop. I'm using a dictionary comprehension to lowercase, but I'm not sure how to append the changed values to my list.
amdardict = [{'1031': 98, '1032': 1, '33007': 70, 'AIRCRAFT_FLIGHT_NUMBER': 'CNFNXQ', 'DAY': 5, 'HEIGHT_OR_ALTITUDE': 1490.0, 'HOUR': 0, 'LATITUDE': 39.71, 'LONGITUDE': -41.79, 'MINUTE': 0, 'MONTH': 10, 'PHASE_OF_AIRCRAFT_FLIGHT': 5, 'TEMPERATURE_DRY_BULB_TEMPERATURE': 289.0, 'WIND_DIRECTION': 219, 'WIND_SPEED': 3.0, 'YEAR': 2019}
{'12101': 248.75, '4006': 55, '7010': 6135, '8009': 3, 'aircraft_flight_number': '????????', 'aircraft_registration_number_or_other_identification': 'AU0155', 'aircraft_tail_number': '??????', 'day': 5, 'destination_airport': '???', 'hour': 0, 'latitude': -34.3166, 'longitude': 151.9333, 'minute': 8, 'month': 10, 'observation_sequence_number': 64, 'origination_airport': '???', 'wind_direction': 208, 'wind_speed': 23.0, 'year': 2019}
]
for d in amdardict: print(dict((k.lower(), v) for k, v in d.items()))
Why modify the original list? Can you create a new empty list and slightly modify your code to append to that new list instead of printing:
new_list = []
for d in amdardict:
new_list.append(dict((k.lower(), v) for k, v in d.items()))
To change the keys in-place, you can use the dict.pop method.
>>> # Copy the list in case we make a mistake
>>> import copy
>>> backup = copy.deepcopy(amdardict)
>>> for d in amdardict:
... # <ake a list of keys() because we can't loop over keys()
... # and change keys simultaneously
... for k in list(d.keys()):
... if not k.islower():
# pop removes the key from the dict and returns the value
... d[k.lower()] = d.pop(k)
...
>>> amdardict
[{'aircraft_flight_number': 'CNFNXQ', 'day': 5, 'height_or_altitude': 1490.0, 'temperature_dry_bulb_temperature': 289.0, 'wind_direction': 219, 'wind_speed': 3.0, 'year': 2019, 'hour': 0, 'latitude': 39.71, 'longitude': -41.79, 'minute': 0, 'month': 10, 'phase_of_aircraft_flight': 5, '1031': 98, '1032': 1, '33007': 70}, {'aircraft_flight_number': '????????', 'aircraft_registration_number_or_other_identification': 'AU0155', 'aircraft_tail_number': '??????', 'day': 5, 'destination_airport': '???', 'hour': 0, 'latitude': -34.3166, 'longitude': 151.9333, 'minute': 8, 'month': 10, 'observation_sequence_number': 64, 'origination_airport': '???', 'wind_direction': 208, 'wind_speed': 23.0, 'year': 2019, '12101': 248.75, '4006': 55, '7010': 6135, '8009': 3}]
Related
I want to iterate through a dictionary array like the following to only copy the 'symbol' and 'product_progress' keys and their corresponding values to new dictionary array.
[{'coin_name': 'Bitcoin', 'coin_id': 'bitcoin', 'symbol': 'btc', 'rank': 1, 'product_progress': 93, 'team': 100, 'token_fundamentals': 100, 'github_activity': 95, 'marketing': 5, 'partnership': 5, 'uniqueness': 5, 'total_score': 96, 'exchange_name': 'Bitfinex', 'exchange_link': 'https://www.bitfinex.com/t/BTCUSD', 'website': 'https://bitcoin.org/en/', 'twitter': 'https://twitter.com/Bitcoin', 'telegram': None, 'whitepaper': 'https://bitcoin.org/en/bitcoin-paper'}, {'coin_name': 'Ethereum', 'coin_id': 'ethereum', 'symbol': 'eth', 'rank': 2, 'product_progress': 87, 'team': 98, 'token_fundamentals': 97, 'github_activity': 100, 'marketing': 5, 'partnership': 5, 'uniqueness': 5, 'total_score': 94, 'exchange_name': 'Gemini', 'exchange_link': 'https://gemini.com/', 'website': 'https://www.ethereum.org/', 'twitter': 'https://twitter.com/ethereum', 'telegram': None, 'whitepaper': 'https://ethereum.org/en/whitepaper/'}] ...
The code I have so far is:
# need to iterate through list of dictionaries
for index in range(len(projectlist3)):
for key in projectlist3[index]:
d['symbol'] = projectlist3[index]['symbol']
d['token_fundamentals'] = projectlist3[index]['token_fundamentals']
print(d)
It's just saving the last entry rather than all of the entries {'symbol': 'eth', 'token_fundamentals': 97}
Given your data:
l = [{
'coin_name': 'Bitcoin',
'coin_id': 'bitcoin',
'symbol': 'btc',
'rank': 1,
'product_progress': 93,
'team': 100,
'token_fundamentals': 100,
'github_activity': 95,
'marketing': 5,
'partnership': 5,
'uniqueness': 5,
'total_score': 96,
'exchange_name': 'Bitfinex',
'exchange_link': 'https://www.bitfinex.com/t/BTCUSD',
'website': 'https://bitcoin.org/en/',
'twitter': 'https://twitter.com/Bitcoin',
'telegram': None,
'whitepaper': 'https://bitcoin.org/en/bitcoin-paper'
}, {
'coin_name': 'Ethereum',
'coin_id': 'ethereum',
'symbol': 'eth',
'rank': 2,
'product_progress': 87,
'team': 98,
'token_fundamentals': 97,
'github_activity': 100,
'marketing': 5,
'partnership': 5,
'uniqueness': 5,
'total_score': 94,
'exchange_name': 'Gemini',
'exchange_link': 'https://gemini.com/',
'website': 'https://www.ethereum.org/',
'twitter': 'https://twitter.com/ethereum',
'telegram': None,
'whitepaper': 'https://ethereum.org/en/whitepaper/'
}]
You can use listcomp
new_l = [{field: d[field] for field in ['symbol', 'token_fundamentals']}
for d in l]
which is better equivalent of this:
new_l = []
for d in l:
new_d = {}
for field in ['symbol', 'token_fundamentals']:
new_d[field] = d[field]
new_l.append(new_d)
Judging by what your writing into d you want to save a list of objects so this would work:
[{"symbol": i['symbol'], "token_fundamentals": i['token_fundamentals']} for i in d]
Result:
[{'symbol': 'btc', 'token_fundamentals': 100}, {'symbol': 'eth', 'token_fundamentals': 97}]
I am new with the concept of dictionaries and trying to learn them. What I have is a dictionary like this:
{'cars': [{'values': [1, 534],
{'values': [25,32,164]
'bikes': [{'values': [23,12,1]
{'values': [2,4]
{'values': [68,69]
{'values': [4,93]
What I try to achieve is add Ids to all inner values starting from 1
If you want the ID as part of the value group, like this:
{'cars': [{'values': [1, 534], 'sedan': 1, 'count': 2, 'ID': 1},
{'values': [25, 32, 164], 'sedan': 1, 'count': 10, 'ID': 2}],
'bikes': [{'values': [23, 12, 1], 'road': 0, 'count': 9},
...
You can do:
for i in range(len(try_dict['cars'])):
try_dict['cars'][i]['ID'] = i+1
If you want what Phydeaux suggests, you can do:
new_dict = {'cars': {}}
for i in range(len(try_dict['cars'])):
new_dict['cars'][i+1] = try_dict['cars'][i]
Which will give you:
{'cars': {1: {'values': [1, 534], 'sedan': 1, 'count': 2},
2: {'values': [25, 32, 164], 'sedan': 1, 'count': 10}}}
If you want not just cars but also bikes (and maybe trucks, trains, whatever...). Use:
new_dict = {}
for key in try_dict.keys():
new_dict[key] = {}
for i in range(len(try_dict[key])):
new_dict[key][i+1] = try_dict[key][i]
This will give you:
{'cars': {1: {'values': [1, 534], 'sedan': 1, 'count': 2},
2: {'values': [25, 32, 164], 'sedan': 1, 'count': 10}},
'bikes': {1: {'values': [23, 12, 1], 'road': 0, 'count': 9},
2: {'values': [2, 4], 'road': 1, 'count': 24},
3: {'values': [68, 69], 'sedan': 0, 'count': 28},
4: {'values': [4, 93], 'sedan': 0, 'count': 6}}}
You can do this using a simple function:
def idx(dict, key):
dict = dict
dict[key].insert(0, 0)
return dict
Full Code:
def idx(dict, key):
dict = dict
dict[key].insert(0, 0)
return dict
dict = {'cars': [{'values': [1, 534],
'sedan': 1,
'count': 2},
{'values': [25,32,164],
'sedan': 1,
'count': 10}],
'bikes': [{'values': [23,12,1],
'road': 0,
'count': 9},
{'values': [2,4],
'road': 1,
'count': 24},
{'values': [68,69],
'sedan': 0,
'count': 28},
{'values': [4,93],
'sedan': 0,
'count': 6}]}
dict = idx(dict, "cars")
print(dict["cars"][1])
Explanation:
Replace dictionary with a new edited dictionary:
dict = {key: [...,...,...]}
dict = idx(dict, key)
Function is using the .insert method to insert 0 for the value of the first index to the key provided.
Learn more about Python .insert() method at:
[
https://www.w3schools.com/python/ref_list_insert.asp
I have several lists of dictionaries, where each dictionary contains a unique id value that is common among all lists. I'd like to combine them into a single list of dicts, where each dict is joined on that id value.
list1 = [{'id': 1, 'value': 20}, {'id': 2, 'value': 21}]
list2 = [{'id': 1, 'sum': 10}, {'id': 2, 'sum': 11}]
list3 = [{'id': 1, 'total': 30}, {'id': 2, 'total': 32}]
desired_output = [{'id': 1, 'value': 20, 'sum': 10, 'total': 30}, {'id': 2, 'value': 21, 'sum': 11, 'total': 32}]
I tried doing something like the answer found at https://stackoverflow.com/a/42018660/7564393, but I'm getting very confused since I have more than 2 lists. Should I try using a defaultdict approach? More importantly, I am NOT always going to know the other values, only that the id value is present in all dicts.
You can use itertools.groupby():
from itertools import groupby
list1 = [{'id': 1, 'value': 20}, {'id': 2, 'value': 21}]
list2 = [{'id': 1, 'sum': 10}, {'id': 2, 'sum': 11}]
list3 = [{'id': 1, 'total': 30}, {'id': 2, 'total': 32}]
desired_output = []
for _, values in groupby(sorted([*list1, *list2, *list3], key=lambda x: x['id']), key=lambda x: x['id']):
temp = {}
for d in values:
temp.update(d)
desired_output.append(temp)
Result:
[{'id': 1, 'value': 20, 'sum': 10, 'total': 30}, {'id': 2, 'value': 21, 'sum': 11, 'total': 32}]
list1 = [{'id': 1, 'value': 20}, {'id': 2, 'value': 21}]
list2 = [{'id': 1, 'sum': 10}, {'id': 2, 'sum': 11}]
list3 = [{'id': 1, 'total': 30}, {'id': 2, 'total': 32}]
# combine all lists
d = {} # id -> dict
for l in [list1, list2, list3]:
for list_d in l:
if 'id' not in list_d: continue
id = list_d['id']
if id not in d:
d[id] = list_d
else:
d[id].update(list_d)
# dicts with same id are grouped together since id is used as key
res = [v for v in d.values()]
print(res)
You can first build a dict of dicts, then turn it into a list:
from itertools import chain
from collections import defaultdict
list1 = [{'id': 1, 'value': 20}, {'id': 2, 'value': 21}]
list2 = [{'id': 1, 'sum': 10}, {'id': 2, 'sum': 11}]
list3 = [{'id': 1, 'total': 30}, {'id': 2, 'total': 32}]
dict_out = defaultdict(dict)
for d in chain(list1, list2, list3):
dict_out[d['id']].update(d)
out = list(dict_out.values())
print(out)
# [{'id': 1, 'value': 20, 'sum': 10, 'total': 30}, {'id': 2, 'value': 21, 'sum': 11, 'total': 32}]
itertools.chain allows you to iterate on all the dicts contained in the 3 lists. We build a dict dict_out having the id as key, and the corresponding dict being built as value. This way, we can easily update the already built part with the small dict of our current iteration.
Here, I have presented a functional approach without using itertools (which is excellent in rapid development work).
This solution will work for any number of lists as the function takes variable number of arguments and also let user to specify the type of return output (list/dict).
By default it returns list as you want that otherwise it returns dictionary in case if you pass as_list = False.
I preferred dictionary to solve this because its fast and search complexity is also less.
Just have a look at the below get_packed_list() function.
get_packed_list()
def get_packed_list(*dicts_lists, as_list=True):
output = {}
for dicts_list in dicts_lists:
for dictionary in dicts_list:
_id = dictionary.pop("id") # id() is in-built function so preferred _id
if _id not in output:
# Create new id
output[_id] = {"id": _id}
for key in dictionary:
output[_id][key] = dictionary[key]
dictionary["id"] = _id # push back the 'id' after work (call by reference mechanism)
if as_list:
return [output[key] for key in output]
return output # dictionary
Test
list1 = [{'id': 1, 'value': 20}, {'id': 2, 'value': 21}]
list2 = [{'id': 1, 'sum': 10}, {'id': 2, 'sum': 11}]
list3 = [{'id': 1, 'total': 30}, {'id': 2, 'total': 32}]
output = get_packed_list(list1, list2, list3)
print(output)
# [{'id': 1, 'value': 20, 'sum': 10, 'total': 30}, {'id': 2, 'value': 21, 'sum': 11, 'total': 32}]
output = get_packed_list(list1, list2, list3, as_list=False)
print(output)
# {1: {'id': 1, 'value': 20, 'sum': 10, 'total': 30}, 2: {'id': 2, 'value': 21, 'sum': 11, 'total': 32}}
list1 = [{'id': 1, 'value': 20}, {'id': 2, 'value': 21}]
list2 = [{'id': 1, 'sum': 10}, {'id': 2, 'sum': 11}]
list3 = [{'id': 1, 'total': 30}, {'id': 2, 'total': 32}]
print(list1+list2+list3)
list1 = [{'id': 1, 'value': 20}, {'id': 2, 'value': 21}]
list2 = [{'id': 1, 'sum': 10}, {'id': 2, 'sum': 11}]
list3 = [{'id': 1, 'total': 30}, {'id': 2, 'total': 32}]
result = []
for i in range(0,len(list1)):
final_dict = dict(list(list1[i].items()) + list(list2[i].items()) + list(list3[i].items()))
result.append(final_dict)
print(result)
output : [{'id': 1, 'value': 20, 'sum': 10, 'total': 30}, {'id': 2, 'value': 21, 'sum': 11, 'total': 32}]
I have a dictionary like that:
{12: {'Soccer': {'value': 31, 'year': 2013}},
23: {'Volley': {'value': 24, 'year': 2012},'Yoga': {'value': 3, 'year': 2014}},
39: {'Baseball': {'value': 2, 'year': 2014},'basket': {'value': 4, 'year': 2012}}}
and i would like to have a dataframe like this:
index column
12 {'Soccer': {'value': 31, 'year': 2013}}
23 {'Volley': {'value': 24, 'year': 2012},'Yoga': {'value': 3, 'year': 2014}}
39 {'Baseball': {'value': 2, 'year': 2014},'basket': {'value': 4, 'year': 2012}}
with each nested dictionary set in a unique column, with the row given by the key of the external dictionary. When I use 'from_dict' with orient parameter equal to index, it considers that keys from the nested dictionaries are the labels of the columns and it makes a square dataframe instead of a single column...
Thanks a lot
Use:
df = pd.DataFrame({'column':d})
Or:
df = pd.Series(d).to_frame('column')
print (df)
column
12 {'Soccer': {'year': 2013, 'value': 31}}
23 {'Volley': {'year': 2012, 'value': 24}, 'Yoga'...
39 {'Baseball': {'year': 2014, 'value': 2}, 'bask...
In [65]: pd.DataFrame(d.values(), index=d.keys(), columns=['column'])
Out[65]:
column
12 ({'Soccer': {'value': 31, 'year': 2013}}, {'Vo...
23 ({'Soccer': {'value': 31, 'year': 2013}}, {'Vo...
39 ({'Soccer': {'value': 31, 'year': 2013}}, {'Vo...
Before writing a function, I would like to be sure there is no pre-built (optimized) solution (like sorted()) that can:
From a dictionary like this one :
tags = {'pinoyako':{'likes': 119, 'comments': 11, 'count': 1}, 'dii':{'likes': 151, 'comments': 3, 'count': 1},'djiphantom3':{'likes': 127, 'comments': 6, 'count': 1}}
Order the keys based on 'likes', 'comments' or 'count'. If it's based on 'likes', the output should be a list ordered :
output = [['dii',151],['djiphantom3',127],['pinoyako',119]]
Use a generator expression within sorted() function with a proper key function:
In [22]: from operator import itemgetter
In [23]: sorted(((k, v['likes']) for k, v in tags.items()), key=itemgetter(1), reverse=True)
Out[23]: [('dii', 151), ('djiphantom3', 127), ('pinoyako', 119)]
You need more entries to illustrate. Check this:
tags = {'pinoyako':{'likes': 119, 'comments': 11, 'count': 1},
'pinoyako2':{'likes': 120, 'comments': 5, 'count': 2},
'djiphantom32':{'likes': 1275, 'comments': 61, 'count': 15},
'dii2':{'likes': 151, 'comments': 33, 'count': 13},
'dii':{'likes': 151, 'comments': 3, 'count': 1},
'djiphantom3':{'likes': 1275, 'comments': 61, 'count': 1}
}
tags_sorted = sorted(tags.items(), key=lambda x: (x[1]['likes'], x[1]['comments'], x[1]['count']))
tags_sorted
Output:
[('pinoyako', {'comments': 11, 'count': 1, 'likes': 119}),
('pinoyako2', {'comments': 5, 'count': 2, 'likes': 120}),
('dii', {'comments': 3, 'count': 1, 'likes': 151}),
('dii2', {'comments': 33, 'count': 13, 'likes': 151}),
('djiphantom3', {'comments': 61, 'count': 1, 'likes': 1275}),
('djiphantom32', {'comments': 61, 'count': 15, 'likes': 1275})]
Then you can do this:
tags_sorted = [[k, v['likes']] for k,v in tags_sorted]
tags_sorted
Output:
[['pinoyako', 119],
['pinoyako2', 120],
['dii', 151],
['dii2', 151],
['djiphantom3', 1275],
['djiphantom32', 1275]]