Python dict - some keys with the same value - python

I'm trying to do a dictionary which include countries GMT time (int number)
for example I have a dict and I want to get the value of it, I tried this code:
countires= {('Jerusalem', 'Athens', 'Bucharest'):2 ,('Bahrain','Qatar'):3}
print(countires.get('Athens'))
and the output is:
None
How I can get result 2?

IIUC, You need create temp dict that have seperate key and search what you want like below:
>>> countires= {('Jerusalem', 'Athens', 'Bucharest'):2 ,('Bahrain','Qatar'):3}
>>> dct = {k:value for key,value in countires.items() for k in key}
>>> print(dct.get('Athens'))
2
If you want to use your original dictionary you can define function and search in keys like below:
>>> def search_multi_key(search, dct):
... for key, value in dct.items():
... if search in key:
... return value
... return None
>>> search_multi_key('Athens', countires)
2

One approach is to create a new dictionary, that uses as key each of the elements of the tuples:
countries= {('Jerusalem', 'Athens', 'Bucharest'):2 , ('Bahrain', 'Qatar'):3}
cities = { key : value for keys, value in countries.items() for key in keys }
print(cities.get('Athens'))
Output
2

Related

Python dictionary: tuple as a key and a list of tuple as a value

I have a dictionary structure in Python that contains only one key-value pair.
The key is a tuple and the value is a list of tuples.
example: {(element1, element2): [(element1.1, element2.1), (element1.2, element2.2).....]}
I am trying to iterate through this dictionary in order to get the key and then the value. Then I want to construct another dictionary that will contain:
{ element1: element2
element1.1: element2.1
element1.2: element2.2 }
What I have tried is the following:
field_dictionary is the dictionary that I previously described.
for (k,v), l in field_dictionary:
log_dictionary[k] = v
for (element1, element2) in l:
log_dictionary[element1] = element2
What I get is an error:
for (k,v), l in field_dictionary:
ValueError: too many values to unpack, expected 2
Can someone help me with this please?
from itertools import chain
spam = {('element1', 'element2'): [('element1.1', 'element2.1'), ('element1.2', 'element2.2')]}
key, value = list(spam.items())[0]
eggs = dict(chain((key,), value))
print(eggs)
output:
{'element1': 'element2', 'element1.1': 'element2.1', 'element1.2': 'element2.2'}
or if you prefer
for key, value in spam.items():
eggs = dict(chain((key, ), value))
print(eggs)
same output

Merging values from 2 dictionaries (Python)

(I'm new to Python!)
Trying to figure out this homework question:
The function will takes a​s input​ two dictionaries, each mapping strings to integers. The function will r​eturn​ a dictionary that maps strings from the two input dictionaries to the sum of the integers in the two input dictionaries.
my idea was this:
def ​add(​dicA,dicB):
dicA = {}
dicB = {}
newdictionary = dicA.update(dicB)
however, that brings back None.
In the professor's example:
print(add({'alice':10, 'Bob':3, 'Carlie':1}, {'alice':5, 'Bob':100, 'Carlie':1}))
the output is:
{'alice':15, 'Bob':103, 'Carlie':2}
My issue really is that I don't understand how to add up the values from each dictionaries. I know that the '+' is not supported with dictionaries. I'm not looking for anyone to do my homework for me, but any suggestions would be very much appreciated!
From the documentation:
update([other])
Update the dictionary with the key/value pairs from other, overwriting existing keys. Return None.
You don't want to replace key/value pairs, you want to add the values for similar keys. Go through each dictionary and add each value to the relevant key:
def ​add(​dicA,dicB):
result = {}
for d in dicA, dicB:
for key in d:
result[key] = result.get(key, 0) + d[key]
return result
result.get(key, 0) will retrieve the value of an existing key or produce 0 if key is not yet present.
First of all, a.update(b) updates a in place, and returns None.
Secondly, a.update(b) wouldn't help you to sum the keys; it would just produce a dictionary with the resulting dictionary having all the key, value pairs from b:
>>> a = {'alice':10, 'Bob':3, 'Carlie':1}
>>> b = {'alice':5, 'Bob':100, 'Carlie':1}
>>> a.update(b)
>>> a
{'alice': 5, 'Carlie': 1, 'Bob': 100}
It'd be easiest to use collections.Counter to achieve the desired result. As a plus, it does support addition with +:
from collections import Counter
def add(dicA, dicB):
return dict(Counter(dicA) + Counter(dicB))
This produces the intended result:
>>> print(add({'alice':10, 'Bob':3, 'Carlie':1}, {'alice':5, 'Bob':100, 'Carlie':1}))
{'alice': 15, 'Carlie': 2, 'Bob': 103}
The following is not meant to be the most elegant solution, but to get a feeling on how to deal with dicts.
dictA = {'Alice':10, 'Bob':3, 'Carlie':1}
dictB = {'Alice':5, 'Bob':100, 'Carlie':1}
# how to iterate through a dictionary
for k,v in dictA.iteritems():
print k,v
# make a new dict to keep tally
newdict={}
for d in [dictA,dictB]: # go through a list that has your dictionaries
print d
for k,v in d.iteritems(): # go through each dictionary item
if not k in newdict.keys():
newdict[k]=v
else:
newdict[k]+=v
print newdict
Output:
Bob 3
Alice 10
Carlie 1
{'Bob': 3, 'Alice': 10, 'Carlie': 1}
{'Bob': 100, 'Alice': 5, 'Carlie': 1}
{'Bob': 103, 'Alice': 15, 'Carlie': 2}
def ​add(​dicA,dicB):
You define a function that takes two arguments, dicA and dicB.
dicA = {}
dicB = {}
Then you assign an empty dictionary to both those variables, overwriting the dictionaries you passed to the function.
newdictionary = dicA.update(dicB)
Then you update dicA with the values from dicB, and assign the result to newdictionary. dict.update always returns None though.
And finally, you don’t return anything from the function, so it does not give you any results.
In order to combine those dictionaries, you actually need to use the values that were passed to it. Since dict.update mutates the dictionary it is called on, this would change one of those passed dictionaries, which we generally do not want to do. So instead, we use an empty dictionary, and then copy the values from both dictionaries into it:
def add (dicA, dicB):
newDictionary = {}
newDictionary.update(dicA)
newDictionary.update(dicB)
return newDictionary
If you want the values to sum up automatically, then use a Counter instead of a normal dictionary:
from collections import Counter
def add (dicA, dicB):
newDictionary = Counter()
newDictionary.update(dicA)
newDictionary.update(dicB)
return newDictionary
I suspect your professor wants to achieve this using more simple methods. But you can achieve this very easily using collections.Counter.
from collections import Counter
def add(a, b):
return dict(Counter(a) + Counter(b))
Your professor probably wants something like this:
def add(a, b):
new_dict = copy of a
for each key/value pair in b
if key in new_dict
add value to value already present in new_dict
else
insert key/value pair into new_dict
return new_dict
You can try this:
def add(dict1, dict2):
return dict([(key,dict1[key]+dict2[key]) for key in dict1.keys()])
I personally like using a dictionary's get method for this kind of merge:
def add(a, b):
result = {}
for dictionary in (a, b):
for key, value in dictionary.items():
result[key] = result.get(key, 0) + value
return result

I have list which have keys of dictionary. How to access the dictionary using these keys dynamically

I have list which have keys of dictionary. How to access the dictionary using these keys dynamically. e.g
key_store = ['test','test1']
mydict = {"test":{'test1':"value"},"test3":"value"}
So how to access mydict using key_store I want to access mydict['test']['test1'].
Note: key_store store depth of keyword means it have keywords only its value will be dictionary like test have dictionary so it have 'test','test1'
You can do this with a simple for-loop.
def get_nested_key(keypath, nested_dict):
d = nested_dict
for key in keypath:
d = d[keypath]
return d
>>> get_nested_key(('test', 'test1'), Dict)
Add error checking as required.
Use recursion:
def get_value(d, k, i):
if not isinstance(d[k[i]], dict):
return d[k[i]]
return get_value(d[k[i]], k, i+1)
The parameters are the dictionary, the list and an index you'll be running on.
The stop condition is simple; Once the value is not a dictionary, you want to return it, otherwise you continue to travel on the dictionary with the next element in the list.
>>> key_store = ['test','test1']
>>> Dict = {"test":{'test1':"value"},"test3":"value"}
>>> def get_value(d, k, i):
... if isinstance(d[k[i]], str):
... return d[k[i]]
... return get_value(d[k[i]], k, i+1)
...
>>> get_value(Dict, key_store, 0)
'value'
You could do this with a simple dictionary reduce:
>>> mydict = {"test": {'test1': "value"}, "test3": "value"}
>>> print reduce(dict.get, ['test', 'test1'], mydict)
value

How can I add a dictionary inside an existing dictionary ,Python

I have the below script in which I have dictionary d with d[domain] date and dns_dic dictionary with domain as keys and rdata = ip as value.
Expected result:
I am wondering how can I make the key of dictionary dns_dic as tuple of domain,date (key values of dictionary d) and value of dns_dic as ip, like
dns_dic = {(domain1,date1):ip1,(domain2,date2):ip2} etc.
dns_dic = defaultdict(set)
d = {domain1:date1,domain2:date2, ..}
if domain in d:
for i in d[domain]:
if jdata.get('time_first') <= i <= jdata.get('time_last'):
dns_dic[dom].update(jdata.get('rdata', []))
This is how jdata looks like:
{"rrname":"c.000a.biz.","time_last":1400243400,"time_first":1388645949,"rdata":["50.21.180.100"]}
{"rrname":"c.000a.biz.","time_last":1389133600,"time_first":1389133600,"rdata":["50.21.180.100"]}
{"rrname": "0001211.com.","time_last":1407101755,"time_first":1389074193,"rdata":["50.21.180.100"]}
Answering your question by example, this is the straightforward way to add tuple as dict key:
# create a dict
d = {}
# add tuple as key with some value
d[('some domain', 'some date')] = 'some ip'
print d
Output:
{('some domain', 'some date'): 'some ip'}
To cast a list to tuple use tuple(lst) where lst is your list.
you can get tuples of (key, value) with dict.items() method.
you can do somthing like:
for item in d.items(): # item is (key,value) tuple
domain,date = item
for jd in jdata:
if jd.get('time_first') <= date <= jd.get('time_last'):
dns_dic[item] = jd.get('rdata',[])
assuming the variables are like
dns_dic = {}
d = {"domain1":1389074195,"domain2":1388645951,"domain3":1389133601}
jdata = [
{"rrname":"c.000a.biz.","time_last":1400243400,"time_first":1388645949,
"rdata":["50.21.180.100"]},
{"rrname":"c.000a.biz.","time_last":1389133600,"time_first":1389133600,
"rdata":["50.21.180.100"]},
{"rrname": "0001211.com.","time_last":1407101755,"time_first":1389074193,
"rdata":["50.21.180.100"]},
]

index python dictionary by value [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Inverse dictionary lookup - Python
Is there a built in way to index a dictionary by value in Python.
e.g. something like:
dict = {'fruit':'apple','colour':'blue','meat':'beef'}
print key where dict[key] == 'apple'
or:
dict = {'fruit':['apple', 'banana'], 'colour':'blue'}
print key where 'apple' in dict[key]
or do I have to manually loop it?
You could use a list comprehension:
my_dict = {'fruit':'apple','colour':'blue','meat':'beef'}
print [key for key, value in my_dict.items() if value == 'apple']
The code above is doing almost exactly what said you want:
print key where dict[key] == 'apple'
The list comprehension is going through all the key, value pairs given by your dictionary's items method, and making a new list of all the keys where the value is 'apple'.
As Niklas pointed out, this does not work when your values could potentially be lists. You have to be careful about just using in in this case since 'apple' in 'pineapple' == True. So, sticking with a list comprehension approach requires some type checking. So, you could use a helper function like:
def equals_or_in(target, value):
"""Returns True if the target string equals the value string or,
is in the value (if the value is not a string).
"""
if isinstance(target, str):
return target == value
else:
return target in value
Then, the list comprehension below would work:
my_dict = {'fruit':['apple', 'banana'], 'colour':'blue'}
print [key for key, value in my_dict.items() if equals_or_in('apple', value)]
You'll have to manually loop it, but if you'll need the lookup repeatedly this is a handy trick:
d1 = {'fruit':'apple','colour':'blue','meat':'beef'}
d1_rev = dict((v, k) for k, v in d1.items())
You can then use the reverse dictionary like this:
>>> d1_rev['blue']
'colour'
>>> d1_rev['beef']
'meat'
Your requirements are more complex than you realize:
You need to handle both list values and plain values
You don't actually need to get back a key, but a list of keys
You could solve this in two steps:
normalize the dict so that every value is a list (every plain value becomes a single-element)
build a reverse dictionary
The following functions will solve this:
from collections import defaultdict
def normalize(d):
return { k:(v if isinstance(v, list) else [v]) for k,v in d.items() }
def build_reverse_dict(d):
res = defaultdict(list)
for k,values in normalize(d).items():
for x in values:
res[x].append(k)
return dict(res)
To be used like this:
>>> build_reverse_dict({'fruit':'apple','colour':'blue','meat':'beef'})
{'blue': ['colour'], 'apple': ['fruit'], 'beef': ['meat']}
>>> build_reverse_dict({'fruit':['apple', 'banana'], 'colour':'blue'})
{'blue': ['colour'], 'apple': ['fruit'], 'banana': ['fruit']}
>>> build_reverse_dict({'a':'duplicate', 'b':['duplicate']})
{'duplicate': ['a', 'b']}
So you just build up the reverse dictionary once and then lookup by value and get back a list of keys.

Categories

Resources