I have a dict structured as below:
{ 'records':[['15','2013-04-02','Mexico','blah','bleh',1,2],['25','2013-04-02','Italy','meh','heh',3,4]], 'attributes':['id','date','location','descr1','descr2','total1','total2'] }
It was created from json using json.load.
How can I iterate through the records key as to make ['records'][0] a key in a new dict and the remainder of each list in ['records'] be the value for that key.
Something like this is what I am thinking, may not even be possible, I am new to Python:
{ '15':['2013-04-02','Mexico','blah','bleh',1,2], '25':['2013-04-02','Italy','meh','heh',3,4] }
Could someone point me in the right direction to going about iterating through the original dict to create the new one?
If d is your dictionary:
In [5]: {rec[0]:rec[1:] for rec in d['records']}
Out[5]:
{'15': ['2013-04-02', 'Mexico', 'blah', 'bleh', 1, 2],
'25': ['2013-04-02', 'Italy', 'meh', 'heh', 3, 4]}
rec_lsts = orgi_dict['records']
new_dict = {}
for l_list in rec_lsts:
new_dict[l_lst[0]] = l_lst[1:]
d = { 'records':[['15','2013-04-02','Mexico','blah','bleh',1,2], ['25','2013-04-02','Italy','meh','heh',3,4]], 'attributes':['id','date','location','descr1','descr2','total1','total2']}
new_d = {}
for a in d['records']:
new_d[a[0]] = a[1:]
print new_d
Related
I have a dict of city names, each having an empty list as a value. I am trying to use
df.iterrows()
to append corresponding names to each dict key(city):
for index, row in df.iterrows():
dict[row['city']].append(row['fullname'])
Can somebody explain why the code above appends all possible 'fullname' values to each dict's key instead of appending them to their respective city keys?
I.e. instead of getting the result
{"City1":["Name1","Name2"],"City2":["Name3","Name4"]}
I'm getting
{"City1":["Name1","Name2","Name3","Name4"],"City2":["Name1","Name2","Name3","Name4"]}
Edit: providing a sample of the dataframe:
d = {'fullname': ['Jason', 'Katty', 'Molly', 'Nicky'],
'city': ['Arizona', 'Arizona', 'California', 'California']}
df = pd.DataFrame(data=d)
Edit 2:
I'm pretty sure that my problem lies in my dict, since I created it in the following way:
cities = []
for i in df['city']:
cities.append(i)
dict = dict.fromkeys(set(cities), [])
when I call dict, i get the correct output:
{"Arizona":[],"California":[]}
However if I specify a key dict['Arizona'], i get this:
{"index":[],"columns":[],"data":[]}
I'm surprised it works at all, because row is a Series.
How about this alternative approach:
for city in your_dict.keys():
your_dict[city] += list(df["fullname"][df["city"] == city])
You should always avoid iterating through dataframes unless it's absolutely necessary.
The problem is indeed .fromkeys - the default value is evaluated once - so all of the keys are "pointing to" the same list.
>>> dict.fromkeys(['one', 'two'], [])
{'one': [], 'two': []}
>>> d = dict.fromkeys(['one', 'two'], [])
>>> d['one'].append('three')
>>> d
{'one': ['three'], 'two': ['three']}
You'd need a comprehension to create a distinct list for each key.
>>> d = { k: [] for k in ['one', 'two'] }
>>> d
{'one': [], 'two': []}
>>> d['one'].append('three')
>>> d
{'one': ['three'], 'two': []}
You are also manually implementing a groupby with your code:
>>> df.groupby('city')['fullname'].agg(list)
city
Arizona [Jason, Katty]
California [Molly, Nicky]
Name: fullname, dtype: object
If you want a dict:
>>> df.groupby('city')['fullname'].agg(list).to_dict()
{'Arizona': ['Jason', 'Katty'], 'California': ['Molly', 'Nicky']}
I'm trying to convert some data in a list to a dictionary. However, I want this dictionary to have multiple keys with multiple values, for example:
The list:
titles = [ "title1", "title2" ]
ids = [ 1, 2 ]
The dictionary:
dictionary = { "title" : "title1", "title2", "id" : 1, 2 }
Sort of like a JSON idea...
There are actually quite a few entries in the lists, so I can't do them each manually. I could use a loop, I suppose?
You probably want a defaultdict:
>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> d['title'].append('title1')
>>> d['title'].append('title2')
>>> print d
defaultdict(<type 'list'>, {'title': ['title1', 'title2']})
In your case, however, you can simply do:
dictionary = {'title':titles, 'id':ids}
You can link items together using tuples also if you'd prefer (using parentheses). This way you can access multiple items with one key. I don't quite know if this is what you're looking for, but I hope it helps.
dictionary = { "title" : ("title1", "title2"), "id" : (1, 2) }
#dictionary[title][0] returns "title1"
#dictionary[title][1] returns "title2"
More info on tuples:
http://docs.python.org/release/1.5.1p1/tut/tuples.html
you can also try this:
>>> titles = ["t1","t2"]
>>> ids = [1,2]
>>> dct = {"titles": titles, "ids":ids}
>>> dct
{'titles': ['t1', 't2'], 'ids': [1, 2]}
Another solution is using dict setdefault function
>>> d = {}
>>> d.setdefault('title', []).append('title1')
>>> d.setdefault('title', []).append('title2')
>>> d
{'title': ['title1', 'title2']}
I would like to create a "translator" type of dict that would assign values that are keys in different dicts, which are nested, to keys in a dict that I created. The problem I run into is that I can't create a value that represents a nested dict key without having to convert that to a string or some other data type, and when I try to use a string as an index to the nested dict, I get an index error. Ideally, my dict would look something like this:
new_dict{
"new_key_1" : ['subdict1']['subdict2']['old_key_1'],
"new_key_2" : ['subdict1']['subdict2']['old_key_2'],
"new_key_3" : ['subdict1']['subdict3']['old_key_3']
}
Then, for each nested dict, I could generate a new dict object with a simple for loop:
for key, value in new_dict.items() :
user_dict_1[key] = OldDict[value]
The nested dicts are very large and I only need a few fields from each, otherwise I could just use the .copy() function to work with the old dicts.
PS- Any help in rewriting this question to be more readable also appreciated.
You're going to need reduce() for this one...
attrmap = {
"new_key_1": ('subdict1', 'subdict2', 'old_key_1'),
...
}
print reduce(lambda x, y: x[y], attrmap[somekey], old_object)
Are you talking something like this?
from pprint import pprint as pp
subdict1 = {'subdict1_item1':1, 'subdict1_item2':2}
subdict2 = {'subdict2_item1':3, 'subdict2_item2':4}
subdict3 = {'subdict3_item1': 5, 'subdict3_item1':6}
olddict = {
'old_key_1': [subdict1, subdict2],
'old_key_2': [subdict1, subdict2],
'old_key_3': [subdict1, subdict3],
}
newdict = {
'new_key_1': olddict['old_key_1'].append('old_key_1'),
'new_key_2': olddict['old_key_2'].append('old_key_2'),
'new_key_3': olddict['old_key_3'].append('old_key_3'),
}
or this
newdict = {
'new_key_1': 'old_key_1',
'new_key_2': 'old_key_2',
'new_key_3': 'old_key_3',
}
def getnew(newkey, newdict, olddict):
if newkey in newdict:
oldkey = newdict[newkey]
if oldkey in olddict:
preitem = olddict[ oldkey ] # returns a list with two items
item = []
item.append([preitem[0]]) # makes subdict1 wrapped in a list
item.append([preitem[1]]) # makes subdict2/3 wrapped in a list
item.append([oldkey])
return item
else:
raise KeyError('newdict has no matching olddict key')
results to:
pp( getnew('new_key_1', newdict, olddict) )
print
pp( getnew('new_key_2', newdict, olddict) )
print
pp( getnew('new_key_3', newdict, olddict) )
[[{'subdict1_item1': 1, 'subdict1_item2': 2}],
[{'subdict2_item1': 3, 'subdict2_item2': 4}],
['old_key_1']]
[[{'subdict1_item1': 1, 'subdict1_item2': 2}],
[{'subdict2_item1': 3, 'subdict2_item2': 4}],
['old_key_2']]
[[{'subdict1_item1': 1, 'subdict1_item2': 2}],
[{'subdict3_item1': 6}],
['old_key_3']]
Let's say I have the following list of python dictionary:
dict1 = [{'domain':'Ratios'},{'domain':'Geometry'}]
and a list like:
list1 = [3, 6]
I'd like to update dict1 or create another list as follows:
dict1 = [{'domain':'Ratios', 'count':3}, {'domain':'Geometry', 'count':6}]
How would I do this?
>>> l1 = [{'domain':'Ratios'},{'domain':'Geometry'}]
>>> l2 = [3, 6]
>>> for d,num in zip(l1,l2):
d['count'] = num
>>> l1
[{'count': 3, 'domain': 'Ratios'}, {'count': 6, 'domain': 'Geometry'}]
Another way of doing it, this time with a list comprehension which does not mutate the original:
>>> [dict(d, count=n) for d, n in zip(l1, l2)]
[{'count': 3, 'domain': 'Ratios'}, {'count': 6, 'domain': 'Geometry'}]
You could do this:
for i, d in enumerate(dict1):
d['count'] = list1[i]
You can do this:
# list index
l_index=0
# iterate over all dictionary objects in dict1 list
for d in dict1:
# add a field "count" to each dictionary object with
# the appropriate value from the list
d["count"]=list1[l_index]
# increase list index by one
l_index+=1
This solution doesn't create a new list. Instead, it updates the existing dict1 list.
Using list comprehension will be the pythonic way to do it.
[data.update({'count': list1[index]}) for index, data in enumerate(dict1)]
The dict1 will be updated with the corresponding value from list1.
I have question about Dictionaries in Python.
here it is:
I have a dict like dict = { 'abc':'a', 'cdf':'b', 'gh':'a', 'fh':'g', 'hfz':'g' }
Now i want to get all Key-Elements by the same value and save it in a new dict.
The new Dict should be look like:
new_dict = { 'b':('cdf'), 'a':('abc','gh'), 'g':('fh','hfz')}
If you are fine with lists instead of tuples in the new dictionary, you can use
from collections import defaultdict
some_dict = { 'abc':'a', 'cdf':'b', 'gh':'a', 'fh':'g', 'hfz':'g' }
new_dict = defaultdict(list)
for k, v in some_dict.iteritems():
new_dict[v].append(k)
If you want to avoid the use of defaultdict, you could also do
new_dict = {}
for k, v in some_dict.iteritems():
new_dict.setdefault(v, []).append(k)
Here's a naive implementation. Someone with better Python skills can probably make it more concise and awesome.
dict = { 'abc':'a', 'cdf':'b', 'gh':'a', 'fh':'g', 'hfz':'g' }
new_dict = {}
for pair in dict.items():
if pair[1] not in new_dict.keys():
new_dict[pair[1]] = []
new_dict[pair[1]].append(pair[0])
print new_dict
This produces
{'a': ['abc', 'gh'], 'b': ['cdf'], 'g': ['fh', 'hfz']}
If you do specifically want tuples as the values in your new dictionary, you can still use defaultdict, and use tuple concatenation. This solution works in Python 3.4+:
from collections import defaultdict
source = {'abc': 'a', 'cdf': 'b', 'gh': 'a', 'fh': 'g', 'hfz': 'g'}
target = defaultdict(tuple)
for key in source:
target[source[key]] += (key, )
print(target)
Which will produce
defaultdict(<class 'tuple'>, {'a': ('abc', 'gh'), 'g': ('fh', 'hfz'), 'b': ('cdf',)})
This will probably be slower than generating a dictionary by list insertion, and will create more objects to be collected. So, you can build your dictionary out of lists, and then map it into tuples:
target2 = defaultdict(list)
for key in source:
target2[source[key]].append(key)
for key in target2:
target2[key] = tuple(target2[key])
print(target2)
Which will give the same result as above.
It can be done this way too, without using any extra functions .
some_dict = { 'abc':'a', 'cdf':'b', 'gh':'a', 'fh':'g', 'hfz':'g' }
new_dict = { }
for keys in some_dict:
new_dict[some_dict[keys]] = [ ]
for keys in some_dict:
new_dict[some_dict[keys]].append(keys)
print(new_dict)