Python: Append a list to an existing dictionary? - python

I have a dictionary with an int as value for each key. I also have total stored in a variable. I want to obtain a percentage that each value represent for the variable and return the percentage to the dictionary as another value for the same key.
I tried to extract the values in a list, then do the operation and append the results to another list. But I don't know how to append that list to the dictionary.
total = 1000
d = {"key_1":150, "key_2":350, "key_3":500}
lst = list(d.values())
percentages = [100 * (i/total) for i in lst]
# Desired dictionary
d
{"key_1": [15%, 150],
"key_2": [35%, 350],
"key_3": [50%, 500]
}

You're better off avoiding the intermediate list and just updating each key as you go:
total = 1000
d = {"key_1":150, "key_2":350, "key_3":500}
for k, v in d.items():
d[k] = [100 * (v / total), v]
While it's technically possible to zip the dict's keys with the values of the list, as long as the keys aren't changed and the list order is kept in line with the values extracted from the dict, the resulting code would reek of code smell, and it's just easier to avoid that list entirely anyway.
Note that this won't put a % sign in the representation, because there is no such thing as a percentage type. The only simple way to shove one in there would be to store it as a string, not a float, e.g. replacing the final line with:
d[k] = [f'{100 * (v / total)}%', v]
to format the calculation as a string, and shove a % on the end.

Here
total = 1000
d = {"key_1": 150, "key_2": 350, "key_3": 500}
d1 = {k: ['{}%'.format(v * 100 / 1000),v] for k, v in d.items()}
print(d1)
output
{'key_1': ['15.0%', 150], 'key_2': ['35.0%', 350], 'key_3': ['50.0%', 500]}

Related

match values between two dictionaries, extract the keys with equals value in new dictionary

For example, I have:
dict1 = {"name":"Cristian","surname":"Rossi","nationality":"Italy","color":"red"}
dict2 = {"country":"Italy","loc":"Milan","other":"red","car":"ford"}
dictionaries is large, some thousands elements.
In this example, the values in both dictionaries are Italy and red. So, I would this result
dict3 = {"nationality":"country","color":"other"}
It may be easier to convert the dictionaries into sets?
Thanks!
Get a set of the common values in both dictionaries. Then get the keys for those values and build a dictionary.
dict1 = {"name":"Cristian","surname":"Rossi","nationality":"Italy","color":"red"}
dict2 = {"country":"Italy","loc":"Milan","other":"red","car":"ford"}
common = set(dict1.values()) & set(dict2.values())
keys1 = [k for k,v in dict1.items() if v in common]
keys2 = [k for k,v in dict2.items() if v in common]
d = {k1:k2 for k1,k2 in zip(keys1, keys2)}
print(d)
Output:
{'nationality': 'country', 'color': 'other'}
Here is one approach which first inverts the dicts and then looks at an intersection of the values. Given that intersection of values it then builds a final result with all of the keys that each value mapped to in the original dicts. Assumes Python 3.
d1 = {"name":"Cristian","surname":"Rossi","nationality":"Italy","color":"red"}
d2 = {"country":"Italy","loc":"Milan","other":"red","car":"ford"}
def inv_dict(d):
inv = {}
for k, v in d.items():
inv.setdefault(v, []).append(k)
return inv
id1 = inv_dict(d1)
id2 = inv_dict(d2)
result = {v:id1[v] + id2[v] for v in id1.keys() & id2.keys()}
print(result)
# {'Italy': ['nationality', 'country'], 'red': ['color', 'other']}
The output is slightly different than what you specified, but it's unclear how your example output would work if the same value appeared in multiple keys in one or both dicts.

Trying to take averages from a list within a dictionary and store them in a new dictionary Python

Here is the initial dictionary
dict = {"Alice":[80,90,70,100,60],"Bob":[70,75,88,77,82],"Cindy":[60,70,90,80,80],"Don":[66,76,76,69,81],"Ellen":[85,88,78,82,68]}
I then go through the keys and find the average
for key, value in dict.items():
val = sum(dict[key]) / 5
This is where I get stuck. I know it will cycle through and get me the averages but I'm lost when it comes to saving the value then storing it in a new Dictionary
You can use a dictionary comprehension to go directly from one dict to another:
d = {"Alice":[80,90,70,100,60],"Bob":[70,75,88,77,82],"Cindy":[60,70,90,80,80],"Don":[66,76,76,69,81],"Ellen":[85,88,78,82,68]}
av = {k: sum(v)/len(v) for k, v, in d.items()}
# av is {'Alice': 80.0, 'Bob': 78.4, 'Cindy': 76.0, 'Don': 73.6, 'Ellen': 80.2}

dictionary comprehension of multiple items in set in python

How do I use dictionary comprehension to obtain the average of the student scores
co_dct = {"Juan":[90,85,98], "Lana":[94,80,100], "Alicia":[100,90], "Sam":[]}
co_dct = d/d[] for d in co_dct
print(co_dct)
As a dictionary comprehension:
>>> co_dct = {"Juan":[90,85,98], "Lana":[94,80,100], "Alicia":[100,90], "Sam":[]}
>>> {k: sum(co_dct[k])/float(len(co_dct[k])) for k in co_dct if co_dct[k]}
{'Juan': 91.0, 'Lana': 91.33333333333333, 'Alicia': 95.0}
Note the use of a filter to guard against division by zero errors when the sample list is empty. This results in the loss of keys that have empty samples, but that seems reasonable since you can't produce an average without data.
Since you are using Python 3 another way is to use statistics.mean():
>>> from statistics import mean
>>> {k: mean(co_dct[k]) for k in co_dct if co_dct[k]}
{'Lana': 91.33333333333333, 'Alicia': 95, 'Juan': 91}
A minor optimisation might be to use co_dct.items() to avoid multiple dict lookups:
>>> {k: mean(values) for k, values in co_dct.items() if values}

New dict of top n values (and keys) from dictionary (Python)

I have a dictionary of names and the number of times the names appear in the phone book:
names_dict = {
'Adam': 100,
'Anne': 400,
'Britney': 321,
'George': 645,
'Joe': 200,
'John': 1010,
'Mike': 500,
'Paul': 325,
'Sarah': 150
}
Preferably without using sorted(), I want to iterate through the dictionary and create a new dictionary that has the top five names only:
def sort_top_list():
# create dict of any 5 names first
new_dict = {}
for i in names_dict.keys()[:5]:
new_dict[i] = names_dict[i]:
# Find smallest current value in new_dict
# and compare to others in names_dict
# to find bigger ones; replace smaller name in new_dict with bigger name
for k,v in address_dict.iteritems():
current_smallest = min(new_dict.itervalues())
if v > current_smallest:
# Found a bigger value; replace smaller key/ value in new_dict with larger key/ value
new_dict[k] = v
# ?? delete old key/ value pair from new_dict somehow
I seem to be able to create a new dictionary that gets a new key/ value pair whenever we iterate through names_dict and find a name/ count that is higher than what we have in new_dict. I can't figure out, though, how to remove the smaller ones from new_dict after we add the bigger ones from names_dict.
Is there a better way - without having to import special libraries or use sorted() - to iterate through a dict and create a new dict of the top N keys with the highest values?
You should use the heapq.nlargest() function to achieve this:
import heapq
from operator import itemgetter
top_names = dict(heapq.nlargest(5, names_dict.items(), key=itemgetter(1)))
This uses a more efficient algorithm (O(NlogK) for a dict of size N, and K top items) to extract the top 5 items as (key, value) tuples, which are then passed to dict() to create a new dictionary.
Demo:
>>> import heapq
>>> from operator import itemgetter
>>> names_dict = {'Adam': 100, 'Anne': 400, 'Britney': 321, 'George': 645, 'Joe': 200, 'John': 1010, 'Mike': 500, 'Paul': 325, 'Sarah': 150}
>>> dict(heapq.nlargest(5, names_dict.items(), key=itemgetter(1)))
{'John': 1010, 'George': 645, 'Mike': 500, 'Anne': 400, 'Paul': 325}
You probably want to use the collections.Counter() class instead. The Counter.most_common() method would have made your use-case trivial to solve. The implementation for that method uses heapq.nlargest() under the hood.
These are not special libraries, they are part of the Python standard library. You otherwise would have to implement a binary heap yourself to achieve this. Unless you are specifically studying this algorithm, there is little point in re-implementing your own, the Python implementation is highly optimised with an extension written in C for some critical functions).
I do not know, why you don't want to use sort and the solution is not perfect and even doesn't match your problem exactly, but I hope it can inspire you to find your own implementation. I think it was only a short example for the real Problem you have.
But as you have seen on the other answer: Normally it is better to use code, that is written before instead of do all the things yourself.
names_dict = {'Joe' : 200, 'Anne': 400, 'Mike': 500, 'John': 1010, 'Sarah': 150, 'Paul': 325, 'George' : 645, 'Adam' : 100, 'Britney': 321}
def extract_top_n(dictionary, count):
#first step: Find the topmost values
highest_values = []
for k,v in dictionary.iteritems():
print k,v, highest_values, len(highest_values)
highest_values.append(v)
l = len(highest_values)
for i in range(l-1):
print i,l
if l-i < 1:
break
if highest_values[l-i-1]>highest_values[l-i-2]:
temp = highest_values[l-i-2]
highest_values[l-i-2] = highest_values[l-i-1]
highest_values[l-i-1] = temp
highest_values = highest_values [:count]
#fill the dirctionary with all entries at least as big as the smallest of the biggest
#but pay attention: If there are more than 2 occurances of one of the top N there will be more than N entries in the dictionary
last_interesting = highest_values[len(highest_values)-1]
return_dictionary = {}
for k,v in dictionary.iteritems():
if v >= last_interesting:
return_dictionary[k] = v
return return_dictionary
print extract_top_n(names_dict,3)

Access keys and vals in listed python-dict

I've got a list k with the 0'th element:
k[0]: {'pattern': 0, 'pos': array([ 9.83698, 106.539 , 130.314 ]), 'id': 1922}
(It looks like a dict, but its a list indeed)
when I iterate through the 0'th element of the list k and print out each element I Get:
for i in k:
print i
=>output:
pattern
pos
id
I'd like to access not only the keys but the values as well. How to do this?
I've also tried to convert the list back into a dict using zip and izip, but same resutlts...i.e. only keys are printed, no values...
any help will be appreciated
thx in advance
you can use k.values() to iterate through the values, or k.items() to iterate through (key, value) pairs
for value in k.values():
print value
for key, value in k.items():
print key, value
The fastest way to iterate over the dictionary you created (it is in fact a dictionary) is not to create the lists of keys/values using k[0].keys(), k[0].values and k[0].items() but using k[0].iteritems() which creates a dictionary iterator that returns just the pairs without allocating lists in the memory.
It also runs much faster for big dictionaries (a being the dictionary):
>>> non_iter_timer = timeit.Timer("for k,v in a.items(): k + v", setup="a = {x:x for x in xrange(10000000)}")
>>> non_iter_timer.repeat(3, 10)
[25.612606023166585, 25.100741935717622, 24.840450306339463]
>>> iter_timer = timeit.Timer("for k,v in a.iteritems(): k + v", setup="a = {x:x for x in xrange(10000000)}")
>>> iter_timer.repeat(3, 10)
[9.26259596885518, 9.198298194571748, 9.77466250122282]

Categories

Resources