Python: Retrieve result from inner dictionary - python-3.x

I'm fairly new to python and I don't know how can I retrieve a value from a inner dictionary:
This is the value I have in my variable:
variable = {'hosts': 1, 'key':'abc', 'result': {'data':[{'licenses': 2, 'id':'john'},{'licenses': 1, 'id':'mike'}]}, 'version': 2}
What I want to do is assign a new variable the number of licenses 'mike' has, for example.
Sorry for such a newbie, and apparent simple question, but I'm only using python for a couple of days and need this functioning asap. I've search the oracle (google) and stackoverflow but haven't been able to find an answer...
PS: Using python3

Working through it and starting with
>>> from pprint import pprint
>>> pprint(variable)
{'hosts': 1,
'key': 'abc',
'result': {'data': [{'id': 'john', 'licenses': 2},
{'id': 'mike', 'licenses': 1}]},
'version': 2}
First, let's get to the result dict:
>>> result = variable['result']
>>> pprint(result)
{'data': [{'id': 'john', 'licenses': 2}, {'id': 'mike', 'licenses': 1}]}
and then to its data key:
>>> data = result['data']
>>> pprint(data)
[{'id': 'john', 'licenses': 2}, {'id': 'mike', 'licenses': 1}]
Now, we have to scan that for the 'mike' dict:
>>> for item in data:
... if item['id'] == 'mike':
... print item['licenses']
... break
...
1
You could shorten that to:
>>> for item in variable['result']['data']:
... if item['id'] == 'mike':
... print item['licenses']
... break
...
1
But much better would be to rearrange your data structure like:
variable = {
'hosts': 1,
'version': 2,
'licenses': {
'john': 2,
'mike': 1,
}
}
Then you could just do:
>>> variable['licenses']['mike']
1

You can use nested references as follows:
variable['result']['data'][1]['licenses'] += 1
variable['result'] returns:
{'data':[{'licenses': 2, 'id':'john'},{'licenses': 1, 'id':'mike'}]}
variable['result']['data'] returns:
[{'licenses': 2, 'id':'john'},{'licenses': 1, 'id':'mike'}]
variable['result']['data'][1] returns:
{'licenses': 1, 'id':'mike'}
variable['result']['data'][1]['licenses'] returns:
1
which we then increment using +=1

Related

python 3 - match and append dicts based on key

Given a very large list, called tsv_data, which resembles:
{'id':1,'name':'bob','size':2},
{'id':2,'name':'bob','size':3},
{'id':3,'name':'sarah','size':2},
{'id':4,'name':'sarah','size':2},
{'id':5,'name':'sarah','size':3},
{'id':6,'name':'sarah','size':3},
{'id':7,'name':'jack','size':5},
And a separate list of all unique strings therein, called names:
{'bob','sarah','jack'}
The aim is to produce the following data structure:
[
{'name':'bob','children':
[
{'id':1,'size':2},
{'id':2,'size':3}
]
},
{'name':'sarah','children':
[
{'id':3,'size':2},
{'id':4,'size':2},
{'id':5,'size':3},
{'id':6,'size':3}
]
},
{'name':'jack','children':
[
{'id':7,'size':5}
]
}
]
Which is challenging for me to write a for loop to restructure as each length is different.
Is there a python solution that is robust to length of each item of name? Please demonstrate, thanks.
Here is a straightforward solution.
tsv_data = [
{'id':1,'name':'bob','size':2},
{'id':2,'name':'bob','size':3},
{'id':3,'name':'sarah','size':2},
{'id':4,'name':'sarah','size':2},
{'id':5,'name':'sarah','size':3},
{'id':6,'name':'sarah','size':3},
{'id':7,'name':'jack','size':5}
]
names = {'bob','sarah','jack'}
expected_keys = ('id', 'size')
result = []
for name in names:
result.append({'name': name,
'children': [ {k: v for k, v in d.items() if k in expected_keys}
for d in tsv_data if d.get('name') == name ]})
# result:
# [{'name': 'sarah',
# 'children': [{'id': 3, 'size': 2},
# {'id': 4, 'size': 2},
# {'id': 5, 'size': 3},
# {'id': 6, 'size': 3}]},
# {'name': 'bob', 'children': [{'id': 1, 'size': 2}, {'id': 2, 'size': 3}]},
# {'name': 'jack', 'children': [{'id': 7, 'size': 5}]}]
In this solution, it iterates over the whole tsv_data for each name. If the tsv_data or names is large and you want to run fast, you could create another dictionary to get a subset of tsv_data by name.

Python dictionary groupby key then count other key values

Assuming I have 4 dictionaries
x = {'id': 1, 'addressed_to': 2, 'status': 'open'}
y = {'id': 2, 'addressed_to': 2, 'status': 'open'}
z = {'id': 3, 'addressed_to': 2, 'status': 'closed'}
z = {'id': 4, 'addressed_to': 3, 'status': 'open'}
I am interested in getting something like this
result = [{'addressed_to': 2, 'open': 2, 'closed':1},{'addressed_to':3 , 'open': 1, 'closed':0} ]
How can I archive this in python3?
One possible answer is to move the dictionaries to a list and iterate thru them to get the required answers. Sample code below. The keys for the result dictionary are values of addressed_to
data_list = {"statsdata": [
{'id': 1, 'addressed_to': 2, 'status': 'open'},
{'id': 2, 'addressed_to': 2, 'status': 'open'},
{'id': 3, 'addressed_to': 2, 'status': 'closed'},
{'id': 4, 'addressed_to': 3, 'status': 'open'}
] }
p_result = {}
def checkItem(item):
if item["status"] == "open":
p_result[item["addressed_to"]]["open"] += 1
if item["status"] == "closed":
p_result[item["addressed_to"]]["closed"] += 1
for item in data_list["statsdata"]:
if item["addressed_to"] not in p_result:
p_result[item["addressed_to"]] = {'open':0, 'closed': 0}
checkItem(item)
else:
checkItem(item)
print(p_result)
Result will appear as
{2: {'open': 2, 'closed': 1}, 3: {'open': 1, 'closed': 0}}

Delete duplicates dictionary inside list by key

I'm newbie in python. I have the next list with dictionaries inside.
l = [{'id': 2, 'source_id': 100},
{'id': 1, 'source_id': 100},
{'id': 3, 'source_id': 1234},
{'id': 5, 'source_id': 200},
{'id': 4, 'source_id': 200}]
And I want to get result like:
l = [{'id': 1, 'source_id': 100},
{'id': 3, 'source_id': 1234},
{'id': 4, 'source_id': 200}]
I understand first step is sorting the list:
sorted_sources_list = sorted(l, key=lambda source: source['id'])
But I don't know how delete duplicate with the greatest id.
You can iterate through each item and add the item to another empty array, but before you add, check if the item already exists within the new array. If it does, its a duplicate item, but if it doesn't, that's obvious, its not duplicate item.
Try:
getId = lambda x: x.get("source_id", None)
l = list(map(lambda x: list(list(x)[-1])[-1], groupby(sorted(l, key=getId), getId)))
Outputs:
[{'id': 1, 'source_id': 100}, {'id': 4, 'source_id': 200}, {'id': 3, 'source_id': 1234}]

python converting a List of Tuples into a Dict with external keys

I have a list of tuples like this
[
(1,'a'),
(2,'b'),
(3,'c'),
(4,'d'),
(5,'e')
]
The result should be a list of dictionaries
[
{'id': 1, 'label': 'a'},
{'id': 2, 'label': 'b'},
{'id': 3, 'label': 'c'},
{'id': 4, 'label': 'd'},
{'id': 5, 'label': 'e'}
]
I'm using python 3.6
The first value in every tuple is named as 'id' and the second value in every tuple is named as 'label'.
I want to get the above result without using loop since the data will be huge.
Is there any built-in method to achieve my result?
Using map
Ex:
data = [
(1,'a'),
(2,'b'),
(3,'c'),
(4,'d'),
(5,'e')
]
keys = ["id", 'label']
print(list(map(lambda x: dict(zip(keys, x)), data)))
#List comprehension
#print([dict(zip(keys, i)) for i in data])
Output:
[{'id': 1, 'label': 'a'},
{'id': 2, 'label': 'b'},
{'id': 3, 'label': 'c'},
{'id': 4, 'label': 'd'},
{'id': 5, 'label': 'e'}]
A simple comprehension will do:
l = [
(1,'a'),
(2,'b'),
(3,'c'),
(4,'d'),
(5,'e')
]
results = [{"id" : id, "label": label} for id, label in l]
If your data is too big you can use a generator (so it will be lazily evaluated):
results = ({"id" : id, "label": label} for id, label in l)
Or use map:
results = map(lambda x: {"id" : x[0], "label": x[1]}, l)
import itertools as it # pip install itertools
ids=[] # lists
a=[
(1,'a'), # input
(2,'b'),
(3,'c'),
(4,'d'),
(5,'e')
]
for i, j in a :
# for j in i:
di=("id", i ,"label", j)
ids.append(dict(it.zip_longest(*[iter(di)] * 2, fillvalue="")))
print(ids)
output :
[{'id': 5, 'label': 'e'}, {'id': 5, 'label': 'e'}, {'id': 5, 'label': 'e'}, {'id': 5, 'label': 'e'}, {'id': 5, 'label': 'e'}]

Match values of two dictionaries and update list inside one of the dictionaries with matching key value pair

Hello have tried to figure this out for some time without much luck so any help is greatly appreciated.
Trying to match the titles of the aa list of dictionaries to the titled of the bb list of dictionaries and update the aa list of dictionaries to a key value combination
aa = [{'link': 'www.home.com', 'title': ['one', 'two', 'three']}, {'link': 'www.away.com', 'title':['two', 'three']}]
bb = [{'id': 1, 'title' :'one'},{'id': 2, 'title': 'two'}, {'id': 3, 'title': 'three'}]
result = [{'link':'www.home.com', 'title':[{'one': 1, 'two': 2, 'three': 3}]}, {'link': 'www.away.com', 'title':[{'two': 2, 'three': 3}]}
]
The result is:
result = [{'link': 'www.home.com', 'title': [{'one': 1, 'two': 2, 'three': 3}]}, {'link': 'www.away.com', 'title': [{'two': 2, 'three': 3}]}]
Refer my code as below:
from copy import deepcopy
aa = [{'link': 'www.home.com', 'title': ['one', 'two', 'three']}, {'link': 'www.away.com', 'title':['two', 'three']}]
bb = [{'id': 1, 'title' :'one'},{'id': 2, 'title': 'two'}, {'id': 3, 'title': 'three'}]
titleids = {}
for b in bb:
titleids[b['title']] = b['id']
result = deepcopy(aa)
for a in result:
a['title'] = [{title:titleids[title] for title in a['title']}]
print(result)
b1={k["title"]:k["id"] for k in bb}
just to solve this example you will do:
[ {'link':l['link'],'title':{i:b1[i] for i in l["title"]}} for l in aa]
[{'link': 'www.home.com', 'title': {'one': 1, 'two': 2, 'three': 3}}, {'link': 'www.away.com', 'title': {'two': 2, 'three': 3}}]
Although if you had many other keys you will do:
[{i:({k:b1[k] for k in j} if i is 'title' else j) for i,j in l.items()} for l in aa]
[{'link': 'www.home.com', 'title': {'one': 1, 'two': 2, 'three': 3}}, {'link': 'www.away.com', 'title': {'two': 2, 'three': 3}}]

Resources