If I have a nested dictionary and varying lists:
d = {'a': {'b': {'c': {'d': 0}}}}
list1 = ['a', 'b']
list2 = ['a', 'b', 'c']
list3 = ['a', 'b', 'c', 'd']
How can I access dictionary values like so:
>>> d[list1]
{'c': {'d': 0}}
>>> d[list3]
0
you can use functools reduce. info here. You have a nice post on reduce in real python
from functools import reduce
reduce(dict.get, list3, d)
>>> 0
EDIT: mix of list and dictioanries
in case of having mixed list and dictionary values the following is possible
d = {'a': [{'b0': {'c': 1}}, {'b1': {'c': 1}}]}
list1 = ['a', 1, 'b1', 'c']
fun = lambda element, indexer: element[indexer]
reduce(fun, list1, d)
>>> 1
Use a short function:
def nested_get(d, lst):
out = d
for x in lst:
out = out[x]
return out
nested_get(d, list1)
# {'c': {'d': 0}}
Related
aa = ['a', 'b', 'c', 'd']
bb = [{'b':1, 'c':0, 'd':2, 'a':5}, {'b':5, 'c':6, 'd':1, 'a':2}]
I want to arrange the dicts in bb list by aa list.
bb = [{'a':5, 'b':1, 'c':0, 'd':2}, {'a':2, 'b':5, 'c':6, 'd':1}]
You can use list- and dict-comprehensions:
aa = ['a', 'b', 'c', 'd']
bb = [{'b':1, 'c':0, 'd':2, 'a':5}, {'b':5, 'c':6, 'd':1, 'a':2}]
output = [{k: dct[k] for k in aa} for dct in bb]
print(output)
# [{'a': 5, 'b': 1, 'c': 0, 'd': 2}, {'a': 2, 'b': 5, 'c': 6, 'd': 1}]
This "sorting" is guaranteed since python 3.7.
This question already has answers here:
How do I print only the last value in a for loop?
(3 answers)
Closed 2 years ago.
How do I get the function to print out only the final count of the list? I keep getting the count from each loop
list = ['A', 'A', 'B', 'A', 'C']
dic = {}
for item in list:
dic[item] = list.count(item)
print (dic)
{'A': 3}
{'A': 3}
{'A': 3, 'B': 1}
{'A': 3, 'B': 1}
{'A': 3, 'B': 1, 'C': 1}
put the print (dic) out of the loop:
list = ['A', 'A', 'B', 'A', 'C']
dic = {}
for item in list:
dic[item] = list.count(item)
print (dic)
I have a existing dict that maps single values to lists.
I want to reverse this dictionary and map from every list entry on the original key.
The list entries are unique.
Given:
dict { 1: ['a', 'b'], 2: ['c'] }
Result:
dict { 'a' : 1, 'b' : 1, 'c' : 2 }
How can this be done?
Here's an option
new_dict = {v: k for k, l in d.items() for v in l}
{'a': 1, 'b': 1, 'c': 2}
You can use a list comprehension to produce a tuple with the key-value pair, then, flatten the new list and pass to the built-in dictionary function:
d = { 1: ['a', 'b'], 2: ['c'] }
new_d = dict([c for h in [[(i, a) for i in b] for a, b in d.items()] for c in h])
Output:
{'a': 1, 'c': 2, 'b': 1}
I have a dictionary like:
d = {1: 'a', 2:'b', 3:'c', 4:'c', 5:'c', 6:'c'}
I want to slice this dictionary such that if the values in the end are same, it should return only the first value encountered. so the return is:
d = {1: 'a', 2:'b', 3:'c'}
I'm using collections.defaultdict(OrderedDict) to maintain sorting by the keys.
Currently, I'm using a loop. Is there a pythonic way of doing this?
UPDATE
the dictionary values can also be dictionaries:
d = {1: {'a': 'a1', 'b': 'b1'}, 2:{'a': 'a1', 'b': 'b2'}, 3:{'a': 'a1', 'b': 'c1'}, 4:{'a': 'a1', 'b': 'c1'}, 5:{'a': 'a1', 'b': 'c1'}, 6:{'a': 'a1', 'b': 'c1'}}
output:
d = {1: {'a': 'a1', 'b': 'b1'}, 2:{'a': 'a1', 'b': 'b2'}, 3:{'a': 'a1', 'b': 'c1'}}
You can use itertools.groupy with a list-comprehension to achieve your result
>>> from itertools import groupby
>>> d = {1: 'a', 2:'b', 3:'c', 4:'c', 5:'c', 6:'c'}
>>> n = [(min([k[0] for k in list(g)]),k) for k,g in groupby(d.items(),key=lambda x: x[1])]
>>> n
>>> [(1, 'a'), (2, 'b'), (3, 'c')]
The above expression can also be written as
>>> from operator import itemgetter
>>> n = [(min(map(itemgetter(0), g)), k) for k, g in groupby(d.items(), key=itemgetter(1))]
You can cast this to dict by simply using
>>> dict(n)
>>> {1: 'a', 2: 'b', 3: 'c'}
This obviously don't maintain order of keys, so you can use OrderedDict
>>> OrderedDict(sorted(n))
>>> OrderedDict([(1, 'a'), (2, 'b'), (3, 'c')])
If you want to get rid of for loop - you can do it this way:
{a:b for b,a in {y:x for x,y in sorted(d.iteritems(), reverse=True)}.iteritems()}
But it is not so pythonic and not so efficient.
Instead of using a ordered dictionary with the keys representing indexes, the more pythonic way is using a list. In this case, you will use indexes instead of keys and will be able to slice the list more effectively.
>>> d = {1: 'a', 2:'b', 3:'c', 4:'c', 5:'c', 6:'c'}
>>> a = list(d.values())
>>> a[:a.index(a[-1])+1]
['a', 'b', 'c']
Just in case, a solution with pandas
import pandas as pd
df = pd.DataFrame(dict(key=list(d.keys()),val=list(d.values())))
print(df)
key val
0 1 a
1 2 b
2 3 c
3 4 c
4 5 c
5 6 c
df = df.drop_duplicates(subset=['val'])
df.index=df.key
df.val.to_dict()
{1: 'a', 2: 'b', 3: 'c'}
Don't know performances issues on biggest dataset or if it is more pythonic.
Nevertheless, no loops.
You can check if two last values are same:
d = OrderedDict({1: 'a', 2:'b', 3:'c', 4:'c', 5:'c', 6:'c'})
while d.values()[-1] == d.values()[-2]:
d.popitem()
print d
# OrderedDict([(1, 'a'), (2, 'b'), (3, 'c')])
I have a dictionary of values that gives the number of occurrences of a value in a list. How can I return a new dictionary that divides the former dictionary into separate dictionaries based on the value?
In other words, I want to sort this dictionary:
>>> a = {'A':2, 'B':3, 'C':4, 'D':2, 'E':3}
to this one.
b = {2: {'A', 'D'}, 3: {'B', 'E'}, 4: {'C'}}
How do I approach the problem?
from collections import defaultdict
a = {'A': 2, 'B': 3, 'C': 4, 'D': 2, 'E': 3}
b = defaultdict(set)
for k, v in a.items():
b[v].add(k)
This is what you'll get:
defaultdict(<class 'set'>, {2: {'D', 'A'}, 3: {'B', 'E'}, 4: {'C'}})
You can convert b to a normal dict afterwards with b = dict(b).
if you are a python beginner like me, you probably wanna try this
a = {'A': 2 , 'B': 3 , 'C' : 4 , 'D' : 2, 'E' : 3}
b = {}
for key in a:
lst = []
new_key = a[key]
if new_key not in b:
lst.append(key)
b[new_key] = lst
else:
b[new_key].append(key)
print(b)
It uses the mutable property of python dictionary to achieve the result you want.