I have two list of dictionaries and I want to find the average of values from each of them based upon the key value. i.e I want to match the keys and average its values from list of dictionaries.
data = {'5649a533c95a8a0bc345d1fe': [{'1': 0.0}, {'2': 28652.343535112403}, {'3': 26505.012833437846}],
'5649a533c95a8a0bc345d20c': [{'1': 28652.343535112403}, {'2': 26505.012833437846}, {'3': 24518.570421292356}]}
I want to match the keys i.e '1' in both the list of dictionaries and then do the average of its respective values.
E.g In the above dataset, I need to get the values 0.0 and 28652.343535112403 matched by the keys i.e '1' and then do the average of the values.
The expected result is [{'1': 20000}, {'2': 230000}, {'3': 23000}]
I am able to iterate the dictionary but I am lost after that.
This is what I have tried to do
for k, v in data.items():
for index, i in enumerate(v, start=1):
print(index, i[str(index)])
Please help.
Try:
d = {}
for x in itertools.chain(data.values()):
for k,v in x.items():
if k in d:
d[k].append(v)
else:
d[k] = [v]
av = {}
for k,v in d.items():
av[k]=sum(v)/len(v)
print av
I got a results:
{'1': 14326.171767556201, '3': 25511.7916273651, '2': 27578.678184275122}
Note: Based on your values on data, you cant have the average:
[{'1': 20000}, {'2': 230000}, {'3': 23000}]
Another try may be-
d = []
for k, v in data.items():
dd = []
for index, i in enumerate(v, start=1):
dd.append((index, i[str(index)]))
d.append(dd)
av_1 = []
av_2 = []
for (x,y) in zip(d[0],d[1]):
l1 = (x[0],y[0])
l2= (x[01],y[1])
l1_av = reduce(lambda x, y: x + y, l1) / len(l1)
l2_av = reduce(lambda x, y: x + y, l2) / len(l2)
av_1.append(l1_av)
av_2.append(l2_av)
print {k:v for k,v in zip(av_1,av_2)}
Output
{1: 14326.171767556201, 2: 27578.678184275122, 3: 25511.7916273651}
Related
Giving this dictionary:
d = {'x': '999999999',
'y': ['888888888', '333333333'],
'z': '666666666',
'p': ['0000000', '11111111', '22222222'] }
is it possible to make a set of tuples ?
The output should be {( x, 999999999),(y,888888888, 333333333),...}
I tried this : x_set = {(k, v) for k, values in d.items() for v in values}
x_set = set()
for k, v in d.items():
items = [k]
if(type(v) == list):
items.extend(v)
else:
items.append(v)
x_set.add(tuple(items))
Check if the dictionary element is a list or not so you know whether to iterate through the element or simply append it.
You could construct a set of tuples with cases depending on whether the dictionary values are lists or not.
d = {'x': '999999999',
'y': ['888888888', '333333333'],
'z': '666666666',
'p': ['0000000', '11111111', '22222222'] }
tuple_set = set(tuple([k] + list(map(int, v)) if isinstance(v,list) else [k, int(v)]) for k,v in d.items())
There are some dictionary in list:
a = [{1: 2}, {1: 3}, {2: 5}, {2: 3}]
All of the keys and values of this dictionary are int type, some dicts have the same key, I want to remain those dictionaries who has the same key and the value is bigger than others, how can I do it?
example:
I want to obtain this list:
[{1: 3}, {2: 5}]
Simple approach using collections.defaultdict:
from collections import defaultdict
a = [{1: 2}, {1: 3}, {2: 5}, {2: 3}]
temp = defaultdict(lambda: float("-inf"))
for item in a:
[(i, v)] = item.items()
temp[i] = max(v, temp[i])
res = [{i: v} for i, v in temp.items()]
print(res)
Output
[{1: 3}, {2: 5}]
In the code the expression float("-inf") acts an unbounded lower value for comparison, this means that:
float("-inf") < x
for any value of x, unless x is float("nan") or float("-inf") itself. Read more in here.
After each first call setting temp[i] for a given i, the value is going to be the first appearing v.
Assuming that each dictionary has only one key/value pair, here is a possible solution. Essentially, create a new dictionary to keep track of the maximum values for each key. Then, turn this into the final list.
def remove_duplicates(dicts):
merged = {}
for d in dicts:
key, value = list(d.items())[0]
if key not in merged:
merged[key] = value
else:
merged[key] = max(
merged[key], value
)
return [
{key: value}
for key, value in merged.items()
]
a = [{1: 2}, {1: 3}, {2: 5}, {2: 3}]
output = {}
for d in a:
k = list(d.keys())[0]
v = list(d.values())[0]
if k not in output.keys():
output[k] = v
else:
if output[k] < v:
output[k] = v
output = [{k:v} for k, v in output.items()]
print(output)
from itertools import groupby
a = [{1: 2}, {1: 3}, {2: 5}, {2: 3}]
[{k, max(y[1] for y in g)} # build up the result by recreating the list of maps by taking the keys in the group and map them to the biggest value in the group
for k, g
in groupby((sorted( # group everything together, so that those touples with the same key (=index 0) are in the same group
((k, v) for m in a for k, v in m.items()) # transform the list of maps to a generator of tuples
, key=lambda x: x[0])), key=lambda x: x[0])]
So here I first transform the list of maps to a list of tuples (which makes much more sense, but that is just me), group them together by the key, and afterwards create new maps for each key, by taking the biggest value inside each group.
Same logic as BrownieInMotion's approach, but with cleaner code using list comprehension for the result.
a = [{1: 2}, {1: 3}, {2: 5}, {2: 3}]
temp = {}
for item in a:
i, v = list(*item.items())
if i not in temp:
temp[i] = v
else:
temp[i] = max(v, temp[i])
print([{i: v} for i, v in temp.items()])
The unpacking usage list(*item.items()) restricts to dictionaries of single key. If you want to remove the restriction, you can go ahead and use list(item.items())[0].
I have a dictionary contains lists of values and a list:
dict={'first':45, 'second':30, 'third':56}
list= [30,45]
I want to compare the value in the dictionary with the list and a match to add to a new dictionary after that, remove from the old dict all the values that are in the new dict: I'm doing something like this:
def get_sessions(self, talks):
result_sessions = {}
for k, v in self.sessions.items():
for i in talks:
if v == i:
result_sessions[k] = v
for k, v in result_sessions.items():
del self.sessions[k]
return result_sessions
Maybe you know a more elegant solution? any help?
This is one approach.
Ex:
d ={'first':45, 'second':30, 'third':56}
lst = [30,45]
result_sessions = {k: v for k, v in d.items() if v in lst}
d = { k : d[k] for k in set(d) - set(result_sessions) }
print(result_sessions)
print(d)
Output:
{'second': 30, 'first': 45}
{'third': 56}
I have a dictionary, and I want to iterate over the keys, test the keys, and then print the keys that pass the test.
For example, my code looks like this at the moment:
x = {4:"a", 1:"b", 0:"c", 9:"d"}
for t in x:
if t > 2:
print t
However, all the output is, is just the key.
How do I get the code to print out the value at the end of the code, instead of the key?
Also, how do I get this in the form of a dictionary, {key : value}?
You could try this: print t, x[t]
Or this:
for key, val in x.items():
if key > 2:
print key, val
If you want to get only the pairs that you're printing into a new dictionary, then you have to put them there:
newdict = {}
for key, val in x.items():
if key > 2:
print key, val
# put all the keys > 2 into the new dict
newdict[key] = val
Of course that solution is printing when it inserts. If you're doing more than just a little script you will get more utility out of breaking functionality out, making sure that any given function does one, and only one, thing:
def filter_dict(x):
newdict = {}
for key, val in x.items():
if key > 2:
# put all the keys > 2 into the new dict
newdict[key] = val
def pretty_print(dct):
for k, v in dct.items():
print k, v
filtered = filter_dict(x)
pretty_print(dct)
This doesn't apply if you're just debugging, of course, and there are ways in which it depends on how large of a program you're writing: if you're doing a simple enough thing then the extra flexibility you get by breaking functionality up is lost because of the extra effort of figuring out exactly what any given thing does. That said: you should generally do it.
Additionally, the most idiomatic way to filter lists on a simple comparison in Python is to use a dict comprehension (new in Python 2.7/3.0):
filtered = {key: val for key, val in x if key > 2}
print [(k,v) for k,v in yourDict.items() if test(k)]
(You could just do k for k,v in... or v for k,v in.... If you only need values, you can use yourDict.values().)
x = {4:"a", 1:"b", 0:"c", 9:"d"}
for t in x:
if t > 2:
print '{}: {}'.format(t, x[t])
Slightly more pythonic:
>>> for key, value in x.iteritems():
... if key > 2:
... print '{}: {}'.format(key, value)
...
4: a
9: d
edit: To just print the value:
>>> for key, value in x.iteritems():
... if key > 2:
... print value
...
a
d
key as well as value:
x = {4:"a", 1:"b", 0:"c", 9:"d"}
for k,v in x.items():
if k>2: print"{%d : %s}"%(k,repr(v))
{4 : 'a'}
{9 : 'd'}
just value:
x = {4:"a", 1:"b", 0:"c", 9:"d"}
for k,v in x.items():
if k>2:print v
a
d
Just the keys:
>>> [k for k in x.iterkeys() if k > 2]
[4, 9]
Just the values:
>>> [v for k,v in x.iteritems() if k > 2]
['a', 'd']
Key-value pairs:
>>> [(k, v) for k,v in x.iteritems() if k > 2]
[(4, 'a'), (9, 'd')]
As a dict:
>>> dict((k,v) for k,v in x.iteritems() if k > 2)
{9: 'd', 4: 'a'}
If you want to create a dictionary with subset of items, you can also use a dictionary comprehension for Python 2.7+:
>>> x = {4:"a", 1:"b", 0:"c", 9:"d"}
>>> y = {k:v for k, v in x.iteritems() if k > 2}
>>> y
{9: 'd', 4: 'a'}
This is only a newer equivalent with only minor syntax differences for what Johnysweb shows in his answer:
>>> y = dict((k, v) for k, v in x.iteritems() if k > 2)
>>> y
{9: 'd', 4: 'a'}
The following list comprehension will print the key and value if key > 2.
Try this:
print [(key, value) for key, value in x.iteritems() if key > 2]
This solution prints the key t and the value in the dictionary x at key t.
x = {4:"a", 1:"b", 0:"c", 9:"d"}
for t in x:
if t > 2:
print t, x[t]
Using lambda function
(lambda x:[(k,v) for k,v in x.iteritems() if k > 2])(x)
Given a list of dictionaries ( each of which have same keys), I want total number of different values with which a given key is associated
$ li = [{1:2,2:3},{1:2,2:4}] $ the expected output is {1:1,2:2}
I came up with the following piece of code...Is there a better way of doing this ?
counts = {}
values = {}
for i in li:
for key,item in i.items():
try:
if item in values[key]:
continue
except KeyError:
else:
try:
counts[key] += 1
except KeyError:
counts[key] = 1
try:
values[key].append(item)
except KeyError:
values[key] = [item]
Something like this is probably more direct:
from collections import defaultdict
counts = defaultdict(set)
for mydict in li:
for k, v in mydict.items():
counts[k].add(v)
That takes care of the collecting / counting of the values. To display them like you want them, this would get you there:
print dict((k, len(v)) for k, v in counts.items())
# prints {1: 1, 2: 2}
Here is yet another alternative:
from collections import defaultdict
counts = defaultdict(int)
for k, v in set(pair for d in li for pair in d.items()):
counts[k] += 1
And the result:
>>> counts
defaultdict(<type 'int'>, {1: 1, 2: 2})
You could so something like this:
li = [{1:2,2:3},{1:2,2:4}]
def makesets(x, y):
for k, v in x.iteritems():
v.add(y[k])
return x
distinctValues = reduce(makesets, li, dict((k, set()) for k in li[0].keys()))
counts = dict((k, len(v)) for k, v in distinctValues.iteritems())
print counts
When I run this it prints:
{1: 1, 2: 2}
which is the desired result.
counts = {}
values = {}
for i in li:
for key,item in i.items():
if not (key in values.keys()):
values[key] = set()
values[key].add(item)
for key in values.keys():
counts[key] = len(values[key])
using flattening list in case dicts are not alway same length:
li=[{1: 2, 2: 3}, {1: 2, 2: 4}, {1: 3}]
dic={}
for i,j in [item for sublist in li for item in sublist.items()]:
dic[i] = dic[i]+1 if i in dic else 1