I have a list of dictionaries e.g.:
list_d = [{"a":1},{"b":2,"c":3}]
(case 1)
for item in list_d:
# add values of each sub-list's dicts
(case 2)
for item in list_d[1]:
# add values of the specific sub-list of dict
(case1) it returns the sum of each sub-list's dict values.
(case2) returns only the keys of the dictionaries.
Is there an efficient way to get the dictionaries of the sub-list(case2) so to add the values?
Here's one way to do it:
reduce(lambda x,y: x + sum(y.values()), list_d, 0)
That is, starting with 0 (as the first x), add the sum of all values in each dict within list_d.
Here's another way:
sum(sum(x.values()) for x in list_d)
That is, sum the (sum of values for each dict in list_d).
As Antti points out it is unclear what you are asking for. I would recommend you having a look at the built-in tools in Python for Functional programming
Consider the following examples:
from operator import add
list_d = [{"a":1},{"b":2,"c":3}]
case_1 = map(lambda d: sum(d.values()), list_d)
case_2 = reduce(add, map(lambda d: sum(d.values()), list_d))
Related
Suppose there is a list of nested lists of floats
L = [[a,b,c],[e,f,g],[h,i,j]]
What kind of function can I define to iterate through the list once and insert the mean of elements of every consecutive list into the same list? I.e. I want to get
L1 = [[a,b,c],[(a+e)/2,(b+f)/2,(c+g)/2],[e,f,g],[(e+h)/2,(f+i)/2,(g+j)/2],[h,i,j]]
I know the function to get the element wise mean of two lists:
from operator import add
new_list = list(map(add,list1,list2))
J = [j/2 for j in new_list]
However inserting this list of mean values back into the same list while maintaining the proper index iteration through the old list proved challenging.
There are two cases:
You don't care if the resulting list is the same list:
new_list = []
for i in range(len(L)-1):
new_list.append(L[i])
new_list.append(list(map(lambda x: sum(x)/len(x), zip(L[i],L[i+1]))))
new_list.append(L[-1])
You want the changes to be done in-place:
i=0
while i < len(L)-1:
new_elem = list(map(lambda x: sum(x)/len(x), zip(L[i],L[i+1])))
L.insert(i+1, new_elem)
i += 2
EDIT: If you're using python 3.4 or above, instead of lambda x: sum(x)/len(x) you can use mean(x) (from the package statistics).
I have the following list:
x = [(27.3703703703704, 2.5679012345679, 5.67901234567901,
6.97530864197531, 1.90123456790123, 0.740740740740741,
0.440136054421769, 0.867718446601942),
(25.2608695652174, 1.73913043478261, 6.07246376811594,
7.3768115942029, 1.57971014492754, 0.710144927536232,
0.4875, 0.710227272727273)]
I'm looking for a way to get the average of each of the lists nested within the main list, and create a new list of the averages. So in the case of the above list, the output would be something like:
[[26.315],[2.145],[5.87],etc...]
I would like to apply this formula regardless of the amount of lists nested within the main list.
I assume your list of tuples of one-element lists is looking for the sum of each unpacked element inside the tuple, and a list of those options. If that's not what you're looking for, this won't work.
result = [sum([sublst[0] for sublst in tup])/len(tup) for tup in x]
EDIT to match changed question
result = [sum(tup)/len(tup) for tup in x]
EDIT to match your even-further changed question
result = [[sum(tup)/len(tup)] for tup in x]
An easy way to acheive this is:
means = [] # Defines a new empty list
for sublist in x: # iterates over the tuples in your list
means.append([sum(sublist)/len(sublist)]) # Put the mean of the sublist in the means list
This will work no matter how many sublists are in your list.
I would advise you read a bit on list comprehensions:
https://docs.python.org/2/tutorial/datastructures.html
It looks like you're looking for the zip function:
[sum(l)/len(l) for l in zip(*x)]
zip combines a collection of tuples or lists pairwise, which looks like what you want for your averages. then you just use sum()/len() to compute the average of each pair.
*x notation means pass the list as though it were individual arguments, i.e. as if you called: zip(x[0], x[1], ..., x[len(x)-1])
r = [[sum(i)/len(i)] for i in x]
This is a simple question but I am unable to code this in python. I want to copy first n items ( supposedly 100 ) i.e both the values and keys into another empty dictionary. I'll give a more clear picture of this. I created a dictionary and sorted it using OrderedDict. My code for sorting it is :
ordP = OrderedDict(reversed(sorted(wcP.items(), key=lambda t: t[1])))
Here ordP is the ordered dictionary I got. This is in descending order. And my original dictionary is wcP. I want to put the first 100 values of ordP i.e the first 100 maximum values of ordP ( sorted according to the keys ) in a new dictionary.
Dictionaries aren't ordered, but if you just want a random selection:
new_values = dict(your_values.items()[:n])
Or, for those obsessed with laziness:
import itertools
new_values = dict(itertools.islice(your_values.iteritems(), n))
If there's a particular sort you want to impose, define a key function that takes the key and value. People usually do lambdas, but there's no reason you can't use a full function.
def example_key_func((key, value)):
return key * value
new_dict = dict(sorted(your_values.items(), key=example_key_func)[:n])
n = 100
assert len(d.keys()) >= n
dic100 = {k:v for k,v in list(d.items())[:n]}
I'm newish to Python (and stackoverflow)...bear with me! I have a dictionary that looks like this:
valueDict[i] = [x,y]
I want to find the minimum key based on the sum of x and y. I know for a dictionary of values I can use:
minVal = min(valueDict, key=valueDict.get)
But I don't think I can modify this approach for a dict of lists.
You can provide any function for the key argument of min. For a dictionary of values you do
minVal = min(dict, key=dict.get) # note no parentheses
If you wanted to the minimum based on the sum, you might do
minVal = min(dict, key=lambda i: sum(dict[i]))
You can use:
minVal = min(d, key=lambda x: sum(d[x]))
where d is the dict.
I have 5 dictionaries and I want a union of their keys.
alldict = [dict1, dict2, dict3, dict4, dict5]
I tried
allkey = reduce(lambda x, y: set(x.keys()).union(y.keys()), alldict)
but it gave me an error
AttributeError: 'set' object has no attribute 'keys'
Am I doing it wrong ? I using normal forloop but I wonder why the above code didn't work.
I think #chuck already answered the question why it doesn't work, but a simpler way to do this would be to remember that the union method can take multiple arguments:
allkey = set().union(*alldict)
does what you want without any loops or lambdas.
Your solution works for the first two elements in the list, but then dict1 and dict2 got reduced into a set and that set is put into your lambda as the x. So now x does not have the method keys() anymore.
The solution is to make x be a set from the very beginning by initializing the reduction with an empty set (which happens to be the neutral element of the union).
Try it with an initializer:
allkey = reduce(lambda x, y: x.union(y.keys()), alldict, set())
An alternative without any lambdas would be:
allkey = reduce(set.union, map(set, map(dict.keys, alldict)))
A simple strategy for non-functional neurons (pun intended):
allkey = []
for dictio in alldict:
for key in dictio:
allkey.append(key)
allkey = set(allkey)
We can convert this code to a much sorter form using set comprehensions:
allkey = {key for dictio in alldict for key in dictio}
This one-liner is still very readable in comparison with the conventional for loop.
The key to convert a nested loop to a list or set comprehension is to write the inner loop (the one that varies faster in the nested loop) as the last index (that is, for key in dictio).
set().union(dict1.keys(),dict2.keys()...)
I tried the list and it didnt work so just putting it up here for anyone.
Just one more way, 'cause what the hay:
a={}; [ a.update(b) for b in alldict ] and a.keys()
or the slightly-more-mysterious
reduce(lambda a, b: a.update(b) or a, alldict, {}).keys()
(I'm bummed that there's no built-in function equivalent to
def f(a,b):
r = {}
r.update(a)
r.update(b)
return r
is there?)
If you only want to union keys of 2 dicts you could use operator |.
Quote from docs:
Return a new set with elements from the set and all others.
Example:
all_keys = (dict1.keys() | dict2.keys())