Iterating Over a Dictionary - python

I am trying to return all the values in a dictionary that have a value greater than the int argurment.
def big_keys(dict, int):
count = []
for u in dict:
if u > int:
count.append(u)
return count
I don't understand why this isn't working. It returns every value in the list rather than just those which are greater than in.

By default, any dict will iterate over its keys, not its values:
>>> d = {'a': 1, 'b': 2}
>>> for i in d:
... print i
...
a
b
To iterate over values, use .values():
>>> for i in d.values():
... print i
...
1
2
With that in mind, your method can be simplified:
def big_keys(d, i):
return [x for x in d.values() if x > i]
I have changed your variable names, since dict and int are both built-ins.
Your method is actually recreating default functionality available in Python. The filter method does what you are trying to do:
>>> d = {'a': 1, 'b': 6, 'd': 7, 'e': 0}
>>> filter(lambda x: x > 5, d.values())
[6, 7]
From your comment it seems you are looking for the keys and not the values. Here is how you would do that:
>>> d = {'a': 21, 'c': 4, 'b': 5, 'e': 30, 'd': 6, 'g': 4, 'f': 2, 'h': 20}
>>> result = []
>>> for k,v in d.iteritems():
... if v > 20:
... result.append(k)
...
>>> result
['a', 'e']
Or, the shorter way:
>>> [k for k,v in d.iteritems() if v > 20]
['a', 'e']

iterating dictionary yields keys for the dictionary.
>>> d = {'key1': 'value1', 'key2': 'value2'}
>>> for x in d:
... print(x)
...
key2
key1
To get values, use dict.values():
>>> for x in d.values():
... print(x)
...
value2
value1
So, you program should read as follow:
def big_keys(dict, int):
count = []
for u in dict.values():
if u > int:
count.append(u)
return count

Related

How do I count each unique value for each key in a dictionary containing lists?

I have the following dictionary:
dict = {'A': [1,1,2], 'B': [1,1,1], 'C': [2,2,2,1,2]}
I want the output to tell me how many of each values I have for each key, e.g.:
if value == 1 -> A, 2; B,3; C,1
if value == 2 -> A, 1; B,0; C,4
So far I have:
for i in dict[i]:
if i == 1:
participants_luck += 1
elif i == 2:
participants_skill += 1
This is a flexible solution to count the occurrences of each different value in the dictionary
dict = {"A": [1,1,2], "B": [1,1,1], "C": [2,2,2,1,2]}
different_values = set()
for values in dict.values():
for el in values:
different_values.add(el)
for possible_value in different_values:
print(possible_value)
for key, values in dict.items():
print(key, sum(value == possible_value for value in values))
print("\n")
Output:
1
A 2
B 3
C 1
2
A 1
B 0
C 4
UPDATE: If you want to handle also non list items in dict you can do like this:
from collections.abc import Iterable
dict = {"A": [1,1,2], "B": [1,1,1], "C": [2,2,2,1,2], "D": 1}
different_values = set()
for values in dict.values():
if isinstance(values, Iterable):
for el in values:
different_values.add(el)
else:
different_values.add(values)
for possible_value in different_values:
print(possible_value)
for key, values in dict.items():
if isinstance(values, Iterable):
print(key, sum(value == possible_value for value in values))
else:
print(key, int(values == possible_value))
print("\n")
And the output will be:
1
A 2
B 3
C 1
D 1
2
A 1
B 0
C 4
D 0
Define a function so you can search for different values if you ever need to. Use the count method to make things very easy for yourself.
d = {'A': [1,1,2], 'B': [1,1,1], 'C': [2,2,2,1,2]}
def foo(value, dictionary):
for key,l in dictionary.items():
print(f"{key} : {l.count(value)}")
foo(1,d)
foo(2,d)
This is a one-liner! You can write a dictionary comprehension. We have a dictionary mydict and a value to count. We first iterate over the items in the dictionary. For each list in the dictionary, we iterate over that list, and find the sum of i == value. Because True counts as 1 and False counts as 0, sum(i == value for i in lst) will give the number of i in the lst which are equal to value. Alternatively, you could do lst.count(value). The sum(...) technique is useful when you want to count a condition other than ==, for example if you wanted to count how many elements are less than the given value.
def count(mydict, value):
return {k: sum(i == value for i in lst) for k, lst in mydict.items()}
# Or,
# return {k: lst.count(value) for k, lst in mydict.items()}
d = {'A': [1,1,2], 'B': [1,1,1], 'C': [2,2,2,1,2]}
count(d, 1) # out: {'A': 2, 'B': 3, 'C': 1}
count(d, 2) # out: {'A': 1, 'B': 0, 'C': 4}
You can then access the counts like so:
result = count(d, 1)
print(f"A: {result['A']}, B: {result['B']}, C: {result['C']}")
Or, if you don't want to hardcode the keys of result:
result = count(d, 1)
for k, v in result.items():
print(f"{k}: {v}")
You could use a Counter:
from collections import Counter
cnts={k: Counter(v) for k,v in di.items()}
# {'A': Counter({1: 2, 2: 1}), 'B': Counter({1: 3}), 'C': Counter({2: 4, 1: 1})}
Then just use a comprehension to get the sub counts as needed:
>>> {k:v[1] for k,v in cnts.items()}
{'A': 2, 'B': 3, 'C': 1}
>>> ({k:v[2] for k,v in cnts.items()}
{'A': 1, 'B': 0, 'C': 4}
Would be interesting making a function to do it.
def count_stuff(any_dict, wanted_val):
counted_dict = {}
for key in any_dict.keys():
count = 0
for element in any_dict[key]:
count += (element == wanted_val)
counted_dict[key] = count
return counted_dict
Running your example...
your_dict = {"A": [1,1,2], "B": [1,1,1], "C": [2,2,2,1,2]}
for i in [1, 2]:
print(i, count_stuff(your_dict, i))
Prints
1 {'A': 2, 'B': 3, 'C': 1}
2 {'A': 1, 'B': 0, 'C': 4}

Subtraction if an items matches in both dictionaries working wrong

I have two dictionaries and I want to subtract value of an item if found in both the dictionaries for which I am doing this:
My Code:
X = {'a':7, 'b':8,'c':9,'d':10}
Y = {'a':3, 'b':4,'c':9}
res = {}
for k,v in X.items():
for m,n in Y.items():
if k == m:
res[k] = v-n
else:
res[k] = v
It is giving me output:
res = {'a': 7, 'b': 8, 'c': 0, 'd': 10}
whereas what I need is this:
res = {'a': 4, 'b': 4, 'c': 0, 'd': 10}
How can I get that ? And also why the above code isn't working ?
insert break statement in 1st condition as below:
X = {'a':7, 'b':8,'c':9,'d':10}
Y = {'a':3, 'b':4,'c':9}
res = {}
for k,v in X.items():
for m,n in Y.items():
if k == m:
res[k] = v-n
break
else:
res[k] = v
print(res)
You can try this.
{k:X.get(k,0)-Y.get(k,0) for k in X.keys()|Y.keys()}
# {'a': 4, 'b': 4, 'c': 0, 'd': 10} -->Order will not be maintained

merging two python dicts and keeping the max key, val in the new updated dict

I need a method where I can merge two dicts keeping the max value when one of the keys, value are in both dicts.
dict_a maps "A", "B", "C" to 3, 2, 6
dict_b maps "B", "C", "D" to 7, 4, 1
final_dict map "A", "B", "C", "D" to 3, 7, 6, 1
I did get the job half done but I didn't figure out how to keep the max value for the 'C' key, value pair.
Used itertools chain() or update().
OK so this works by making a union set of all possible keys dict_a.keys() | dict_b.keys() and then using dict.get which by default returns None if the key is not present (rather than throwing an error). We then take the max (of the one which isn't None).
def none_max(a, b):
if a is None:
return b
if b is None:
return a
return max(a, b)
def max_dict(dict_a, dict_b):
all_keys = dict_a.keys() | dict_b.keys()
return {k: none_max(dict_a.get(k), dict_b.get(k)) for k in all_keys}
Note that this will work with any comparable values -- many of the other answers fail for negatives or zeros.
Example:
Inputs:
dict_a = {'a': 3, 'b': 2, 'c': 6}
dict_b = {'b': 7, 'c': 4, 'd': 1}
Outputs:
max_dict(dict_a, dict_b) # == {'b': 7, 'c': 6, 'd': 1, 'a': 3}
What about
{
k:max(
dict_a.get(k,-float('inf')),
dict_b.get(k,-float('inf'))
) for k in dict_a.keys()|dict_b.keys()
}
which returns
{'A': 3, 'D': 1, 'C': 6, 'B': 7}
With
>>> dict_a = {'A':3, 'B':2, 'C':6}
>>> dict_b = {'B':7, 'C':4, 'D':1}
Here is a working one liner
from itertools import chain
x = dict(a=30,b=40,c=50)
y = dict(a=100,d=10,c=30)
x = {k:max(x.get(k, 0), y.get(k, 0)) for k in set(chain(x,y))}
In[83]: sorted(x.items())
Out[83]: [('a', 100), ('b', 40), ('c', 50), ('d', 10)]
This is going to work in any case, i.e for common keys it will take the max of the value otherwise the existing value from corresponding dict.
Extending this so you can have any number of dictionaries in a list rather than just two:
a = {'a': 3, 'b': 2, 'c': 6}
b = {'b': 7, 'c': 4, 'd': 1}
c = {'c': 1, 'd': 5, 'e': 7}
all_dicts = [a,b,c]
from functools import reduce
all_keys = reduce((lambda x,y : x | y),[d.keys() for d in all_dicts])
max_dict = { k : max(d.get(k,0) for d in all_dicts) for k in all_keys }
If you know that all your values are non-negative (or have a clear smallest number), then this oneliner can solve your issue:
a = dict(a=3,b=2,c=6)
b = dict(b=7,c=4,d=1)
merged = { k: max(a.get(k, 0), b.get(k, 0)) for k in set(a) | set(b) }
Use your smallest-possible-number instead of the 0. (E. g. float('-inf') or similar.)
Yet another solution:
a = {"A":3, "B":2, "C":6}
b = {"B":7, "C":4, "D":1}
Two liner:
b.update({k:max(a[k],b[k]) for k in a if b.get(k,'')})
res = {**a, **b}
Or if you don't want to change b:
b_copy = dict(b)
b_copy.update({k:max(a[k],b[k]) for k in a if b.get(k,'')})
res = {**a, **b_copy}
> {'A': 3, 'B': 7, 'C': 6, 'D': 1}

Python: how to search within a homogenous values dictionary

I have this dictionary:
dict = {'a': [1, 'Hello', 3], 'b': {1, 2, 90}, 'c': (1, 2, 'tuple'), 'd': 3}
I tried to print each key contains the value 3. The output has to be a and d
I tired something like this:
[key for key, vals in dict.items() if 3 in vals]
but an error: int is not iterable
I also tried to use for :
>>> for i in dict.values():
... if 3 in dict.values():
... print(i)
I also tried this but nothing works
>>> for i in dict.keys():
... if 3 in dict[i]:
... print(i)
PART 2: Let us say I am able to print the key if the value contains 3, then how can I get the index if the value is list or tuple?
[key for key, vals in dict.items() if 3==vals or 3 in vals]
The error you get is because not all your values are of the same type.
Your evaluation needs to be if key equals to 3 then return true, or if the value is a container, check if 3 is part of it.
To get an index of a value in a list OR a tuple, you can use
>>> l = [1, 2, 'just', 3, 'p']
>>> l.index(3)
3
>>> t = (1, 2, 'word', 3)
>>> t.index(3)
3
>>>
for k, v in dict.items():
try:
if 3 in v:
print(k)
except TypeError:
if v == 3:
print(k)
Another way is to test if the value of the key is not scalar, before trying to use in:
def in_key(value, vals):
if isinstance(vals, (list, tuple, set)):
return value in vals
else:
return value == vals
lst = [key for key, vals in dict.items() if in_vals(3, vals)]
Your code is almost right, just check the item equal or contained in a set of vals:
dict = {'a': [1, 'Hello', 3], 'b': {1, 2, 90}, 'c': (1, 2, 'tuple'), 'd': 3}
print [key for key, vals in dict.items() if 3 == vals or 3 in vals]
['a', 'd']
Here you have a live example

How to iterate over a dictionary and find the max values python?

I have a dictionary like such:
aDict = {'a': [1,2,3],
'b': [2,3,4],
'c': [3,3,6], ...}
How would I create a list that stores the maximum values at each index, (0,1,2).
Thanks!
If I understand right, you want something like this:
>>> aDict = {'a':[1,2,3],'b':[2,3,4],'c':[3,3,6]}
>>> aList = [max(aDict[k]) for k in sorted(aDict.keys())]
>>> print aList
[3, 4, 6]
Or maybe this:
>>> aDict = {'a':[1,2,3],'b':[2,3,4],'c':[3,3,6]}
>>> aDict2 = dict((k, max(aDict[k])) for k in aDict.keys())
>>> print aDict2
{'a': 3, 'c': 6, 'b': 4}

Categories

Resources