Replace key references by corresponding values in dict values - python

In the following dictionary, a user can refer to a key as a variable for defining another value:
d = {'a_key': 'a_value', 'b_key': 'a_key+1'}
I have to replace these references by the corresponding values, in order to obtain this desired output:
d = {'a_key': 'a_value', 'b_key': 'a_value+1'}
I thought it would be easy, but this one drives crazy since a few hours. I got to this code:
for k in d.keys():
print("key: " + k)
print("value: " + d[k])
for v in d.values():
print("value_before: " + v)
v = v.replace(k, d[k])
print("value_after: " + v)
print(d)
The output is:
key: a_key
value: a_value
value_before: a_value
value_after: a_value
value_before: a_key+1
value_after: a_value+1
key: b_key
value: a_key+1 # WHY??
value_before: a_value
value_after: a_value
value_before: a_key+1
value_after: a_key+1
{'a_key': 'a_value', 'b_key': 'a_key+1'}
As we see, the first iteration seems to do the job, before it is cancelled by the second one. I just don't unserstand why. I also tried to adapt the very specific answers to that question: Replace values in dict if value of another key within a nested dict is found in value, but to no avail. I'm looking for a general answer to: how to get the desired output?
From a theoretic point of view, I would also like to understand why the "b_value" is reset to a_key+1. Thanks.

The problem is that you are modifying temporary variable v but you are not placing the modified values back in the dictionary.
Try replacing :
for v in d.values():
v = v.replace(k, d[k])
with:
for r,v in d.items():
d[r] = v.replace(k, d[k])

Related

Check if value of one dictionary is the key for the other

I basically want to check if the value in one dictionary is the key in the other.
So for example, I have two dictionaries
a = {armani: jeans, dolce: gabbana}
b = {jeans: robo, jobs: versace}
I wrote code to do the check such that it only obtains the values that is the key in the other dictionary. So in this case, I just want to display {armani: robo} as jeans was already in both. So like the value of jeans in the second dictionary then becomes the main value in the new final dictionary
This is the code:
{k:v for k,v in a.items() if v in b.items()}
But it doesn't work and I don't know how to do the check to see if the value is the key in another list
This should work:
{k:b[v] for k,v in a.items() if v in b}
You were just missing two elements:
You don't need to write if v in b.items() because Python interprets if v in b as "if v is in the keys of b".
You need to map k not to v itself, but to v's value in b, which is b[v].
Alternatively, you could filter with set intersection.
a = {'armani': 'jeans', 'dolce': 'gabbana'}
b = {'jeans': 'robo', 'jobs': 'versace'}
c = set(a.values()).intersection(b)
d = {k:b[k] for k in c}
# or as a one-liner
e = {k:b[k] for k in set(a.values()).intersection(b)}
It might be faster than looping through the whole dictionary.
I think you need:
a = {"armani": "jeans", "dolce": "gabbana"}
b = {"jeans": "robo", "jobs": "versace"}
res = {k1:v2 for k1,v1 in a.items() for k2,v2 in b.items() if v1 ==k2}
print(res)
Output:
{'armani': 'robo'}

Python: Understanding loops

I'm super new to Python, I think this isn't a problem with my syntax, but with my understanding...(and I'm sure there's an easier way to do this, but right now I really just want some help with what is wrong with my understanding of loops)
Considering some code that goes roughly like...
for k, v in dict1.iteritems():
if v not in dict2.keys():
print "adding %s to dict2" % v
dict2[v] = "whatever"
My loop cycles through the "if" for every single key in dict1, I can tell because of the print statement. It's as though the for loop uses the original definition of dict2 each time, and doesn't consider whatever happened in the last iteration.
I had expected that once I went through the for loop once, with a unique value from dict1, any duplicate values from dict1 would skip the if step of the loop because that value was already added to dict2 in a previous iteration. Is that incorrect?
Thanks so much!
Joe
more context: hi, here is what I actually have (first thing I've ever written, so maybe it would be helpful to me if you critiqued the whole thing!) I have a file listing employees and their designated "work unit" (substitute the word "work unit" for "team" if it helps), and I figured how to import that into a dictionary. Now I want to turn that into a dictionary of "work units" as keys, with an associated employee as the value. For now it doesn't matter which employee, I just am trying to figure out how to get a dictionary containing 1 key for each work unit). what I have so far...
sheet = workbook.sheet_by_index(0)
r = sheet.nrows
i = 1
employees = {}
'''Importing employees into a employees dictionary'''
while i < r:
hrid = sheet.row_values(i,0,1)
name = sheet.row_values(i,1,2)
wuid = sheet.row_values(i,2,3)
wuname = sheet.row_values(i,3,4)
wum = sheet.row_values(i,4,5)
parentwuid = sheet.row_values(i,5,6)
employees[str(i)] = hrid, name, wuid, wuname, wum, parentwuid
i += 1
'''here's where I create workunits dictionary and try to begin to populate'''
workunits = {}
for k, v in employees.iteritems():
if v[2] not in workunits.keys():
print "Adding to %s to the dictionary" % (v[2])
workunits[str(v[2])] = v[1]
Solution: OK, finally got there...it's just because I hadn't called str() on v[2] in my if statement. Thanks all!
You're checking to see if v (a value) is in dict2's keys, but then adding it as a key. Is that what you want it to do?
If maybe you meant to copy elements over this might be what you meant to do:
if k not in dict2.keys():
print "adding %s to dict2" % v
dict2[k] = v
This question is more for codereview than for SO, but
for k, v in dict1.iteritems(): # here's you iterating through tuples like (key, value) from dict1
if v not in dict2.keys(): # list of dict2 keys created each time and you iterating through the whole list trying to find v
print "adding %s to dict2" % v
dict2[v] = "whatever"
you can simplify (and improve performance) your code like
for k, v in dict1.iteritems(): # here's you iterating through tuples like (key, value) from dict1
if v not in dict2: # just check if v is already in dict2
print "adding %s to dict2" % v
dict2[v] = "whatever"
or even
dict2 = {v:"whatever" for v in dict1.values()}
You mention in your comment "I want to dict2 to contain a key for every unique value in dict1".
There's a compact syntax for getting the result you want.
d_1 = {1: 2, 3: 4, 5: 6}
d_2 = {v: "whatever" for v in d_1.itervalues()}
However, this doesn't address you concern about about duplicates.
What you could do is make a set of the values in d_1 (no duplicates) and then create d_2 from that:
values_1 = set(d_1.itervalues())
d_2 = {v: "whatever" for v in values_1}
Another option is to use the fromkeys method, but to my eye this isn't as clear as the dictionary comprehension.
d_2 = {}.fromkeys(set(d_1.itervalues()))
Unless you have reason to believe that processing duplicates is slowing down your code unacceptably, I'd say you should use the most direct method to express what you want.
For your application of converting the employee_to_team dictionary to a team_to_employee dictionary, you could then do:
team_to_employee = {v: k for k, v in employee_to_team.iteritems()}
This because you don't care which employee gets represented and this method will just overwrite each time a duplicate is encountered.

How can you print a key given a value in a dictionary for Python?

For example lets say we have the following dictionary:
dictionary = {'A':4,
'B':6,
'C':-2,
'D':-8}
How can you print a certain key given its value?
print(dictionary.get('A')) #This will print 4
How can you do it backwards? i.e. instead of getting a value by referencing the key, getting a key by referencing the value.
I don't believe there is a way to do it. It's not how a dictionary is intended to be used...
Instead, you'll have to do something similar to this.
for key, value in dictionary.items():
if 4 == value:
print key
In Python 3:
# A simple dictionary
x = {'X':"yes", 'Y':"no", 'Z':"ok"}
# To print a specific key (for instance the 2nd key which is at position 1)
print([key for key in x.keys()][1])
Output:
Y
The dictionary is organized by: key -> value
If you try to go: value -> key
Then you have a few problems; duplicates, and also sometimes a dictionary holds large (or unhashable) objects which you would not want to have as a key.
However, if you still want to do this, you can do so easily by iterating over the dicts keys and values and matching them as follows:
def method(dict, value):
for k, v in dict.iteritems():
if v == value:
yield k
# this is an iterator, example:
>>> d = {'a':1, 'b':2}
>>> for r in method(d, 2):
print r
b
As noted in a comment, the whole thing can be written as a generator expression:
def method(dict, value):
return (k for k,v in dict.iteritems() if v == value)
Python versions note: in Python 3+ you can use dict.items() instead of dict.iteritems()
target_key = 4
for i in dictionary:
if dictionary[i]==target_key:
print(i)
Within a dictionary if you have to find the KEY for the highest VALUE please do the following :
Step 1: Extract all the VALUES into a list and find the Max of list
Step 2: Find the KEY for the particular VALUE from Step 1
The visual analyzer of this code is available in this link : LINK
dictionary = {'A':4,
'B':6,
'C':-2,
'D':-8}
lis=dictionary.values()
print(max(lis))
for key,val in dictionary.items() :
if val == max(lis) :
print("The highest KEY in the dictionary is ",key)
I think this is way easier if you use the position of that value within the dictionary.
dictionary = {'A':4,
'B':6,
'C':-2,
'D':-8}
# list out keys and values separately
key_list = list(dictionary.keys())
val_list = list(dictionary.values())
# print key with val 4
position = val_list.index(4)
print(key_list[position])
# print key with val 6
position = val_list.index(6)
print(key_list[position])
# one-liner
print(list(my_dict.keys())[list(my_dict.values()).index(6)])
Hey i was stuck on a thing with this for ages, all you have to do is swap the key with the value e.g.
Dictionary = {'Bob':14}
you would change it to
Dictionary ={1:'Bob'}
or vice versa to set the key as the value and the value as the key so you can get the thing you want

modify a dictionary

I need to modify a dictionary. I have a dictionary with integer values and want to replace each value with the fraction of the total of all values, eg.:
census={a:4, b:1, c:3}; turnIntoFractions(census), should then print {a:0.5, b:0,125 ,c:0,375 }
I was thinking something like:
def turnIntoFractions:
L=d.keys()
total=sum(L)
F=[]
for count in L:
f.append(float(count/float(total))
return F
I'm kind of stuck, and it isn't working..
You can use dictionary comprehension.
def turnIntoFractions(d):
total = float(sum(d.values()))
return {key:(value/total) for key,value in d.items()}
Your first problem is that you are doing the sum of the keys, not the values:
total = sum(d.values())
Now, you can just modify the dictionary inline, instead of putting it into a new list:
for key in d.keys():
d[key] /= total # or d[key] = d[key] / total
My previous code goes through each key, retrieves the value, then divides by total, and then finally stores it back into d[key].
If you want a new dictionary returned, instead of just modifying the existing one, you can just start out with e = d.copy(), then use e instead.
You seem to want to edit the dict in place, but your code returns a new object, which is actually better practice.
def turnIntoFractions(mydict):
values=d.values()
total=float(sum(values))
result = {}
for key, val in mydict.items():
result[key] = val/total
return result
your code has the right idea, but also a few small mistakes.
here's a working code:
def turnIntoFractions(d):
L=d.values()
total=sum(L)
f=[]
for count in L:
f.append(float(count/float(total)))
return f
census={'a':4, 'b':1, 'c':3}
print(turnIntoFractions(census))
note that python is case sensitive so f is not the same as F, and also keys that are strings need to be quoted
Use dictionary comprehension
sum = float(sum(census.itervalues()))
newDict = {k : (v / sum) for k,v in census.iteritems()}
for python 2.6:
newDict = dict((k,v /sum) for (k,v) in census.iteritems())
The following Python code will modify the dictionary's keys to float values.
def turnIntoFractions(mydict):
total = sum(mydict.values())
for key in mydict:
mydict[key] = float(mydict[key]) / total

How to print a dictionary's key?

I would like to print a specific Python dictionary key:
mydic = {}
mydic['key_name'] = 'value_name'
Now I can check if mydic.has_key('key_name'), but what I would like to do is print the name of the key 'key_name'. Of course I could use mydic.items(), but I don't want all the keys listed, merely one specific key. For instance I'd expect something like this (in pseudo-code):
print "the key name is", mydic['key_name'].name_the_key(), "and its value is", mydic['key_name']
Is there any name_the_key() method to print a key name?
Edit:
OK, thanks a lot guys for your reactions! :) I realise my question is not well formulated and trivial. I just got confused because I realised 'key_name' and mydic['key_name'] are two different things and I thought it would be incorrect to print the 'key_name' out of the dictionary context. But indeed I can simply use the 'key_name' to refer to the key! :)
A dictionary has, by definition, an arbitrary number of keys. There is no "the key". You have the keys() method, which gives you a python list of all the keys, and you have the iteritems() method, which returns key-value pairs, so
for key, value in mydic.iteritems() :
print key, value
Python 3 version:
for key, value in mydic.items() :
print (key, value)
So you have a handle on the keys, but they only really mean sense if coupled to a value. I hope I have understood your question.
Additionally you can use....
print(dictionary.items()) #prints keys and values
print(dictionary.keys()) #prints keys
print(dictionary.values()) #prints values
Hmm, I think that what you might be wanting to do is print all the keys in the dictionary and their respective values?
If so you want the following:
for key in mydic:
print "the key name is" + key + "and its value is" + mydic[key]
Make sure you use +'s instead of ,' as well. The comma will put each of those items on a separate line I think, where as plus will put them on the same line.
dic = {"key 1":"value 1","key b":"value b"}
#print the keys:
for key in dic:
print key
#print the values:
for value in dic.itervalues():
print value
#print key and values
for key, value in dic.iteritems():
print key, value
Note:In Python 3, dic.iteritems() was renamed as dic.items()
The name of the key 'key_name' is 'key_name', therefore
print('key_name')
or whatever variable you have representing it.
In Python 3:
# A simple dictionary
x = {'X':"yes", 'Y':"no", 'Z':"ok"}
# To print a specific key (for example key at index 1)
print([key for key in x.keys()][1])
# To print a specific value (for example value at index 1)
print([value for value in x.values()][1])
# To print a pair of a key with its value (for example pair at index 2)
print(([key for key in x.keys()][2], [value for value in x.values()][2]))
# To print a key and a different value (for example key at index 0 and value at index 1)
print(([key for key in x.keys()][0], [value for value in x.values()][1]))
# To print all keys and values concatenated together
print(''.join(str(key) + '' + str(value) for key, value in x.items()))
# To print all keys and values separated by commas
print(', '.join(str(key) + ', ' + str(value) for key, value in x.items()))
# To print all pairs of (key, value) one at a time
for e in range(len(x)):
print(([key for key in x.keys()][e], [value for value in x.values()][e]))
# To print all pairs (key, value) in a tuple
print(tuple(([key for key in x.keys()][i], [value for value in x.values()][i]) for i in range(len(x))))
Since we're all trying to guess what "print a key name" might mean, I'll take a stab at it. Perhaps you want a function that takes a value from the dictionary and finds the corresponding key? A reverse lookup?
def key_for_value(d, value):
"""Return a key in `d` having a value of `value`."""
for k, v in d.iteritems():
if v == value:
return k
Note that many keys could have the same value, so this function will return some key having the value, perhaps not the one you intended.
If you need to do this frequently, it would make sense to construct the reverse dictionary:
d_rev = dict(v,k for k,v in d.iteritems())
Update for Python3: d.iteritems() is not longer supported in Python 3+ and should be replaced by d.items()
d_rev = {v: k for k, v in d.items()}
# highlighting how to use a named variable within a string:
mapping = {'a': 1, 'b': 2}
# simple method:
print(f'a: {mapping["a"]}')
print(f'b: {mapping["b"]}')
# programmatic method:
for key, value in mapping.items():
print(f'{key}: {value}')
# yields:
# a 1
# b 2
# using list comprehension
print('\n'.join(f'{key}: {value}' for key, value in dict.items()))
# yields:
# a: 1
# b: 2
Edit: Updated for python 3's f-strings...
Make sure to do
dictionary.keys()
rather than
dictionary.keys
import pprint
pprint.pprint(mydic.keys())
Or you can do it that manner:
for key in my_dict:
print key, my_dict[key]
dict = {'name' : 'Fred', 'age' : 100, 'employed' : True }
# Choose key to print (could be a user input)
x = 'name'
if x in dict.keys():
print(x)
What's wrong with using 'key_name' instead, even if it is a variable?
Probably the quickest way to retrieve only the key name:
mydic = {}
mydic['key_name'] = 'value_name'
print mydic.items()[0][0]
Result:
key_name
Converts the dictionary into a list then it lists the first element which is the whole dict then it lists the first value of that element which is: key_name
I'm adding this answer as one of the other answers here (https://stackoverflow.com/a/5905752/1904943) is dated (Python 2; iteritems), and the code presented -- if updated for Python 3 per the suggested workaround in a comment to that answer -- silently fails to return all relevant data.
Background
I have some metabolic data, represented in a graph (nodes, edges, ...). In a dictionary representation of those data, keys are of the form (604, 1037, 0) (representing source and target nodes, and the edge type), with values of the form 5.3.1.9 (representing EC enzyme codes).
Find keys for given values
The following code correctly finds my keys, given values:
def k4v_edited(my_dict, value):
values_list = []
for k, v in my_dict.items():
if v == value:
values_list.append(k)
return values_list
print(k4v_edited(edge_attributes, '5.3.1.9'))
## [(604, 1037, 0), (604, 3936, 0), (1037, 3936, 0)]
whereas this code returns only the first (of possibly several matching) keys:
def k4v(my_dict, value):
for k, v in my_dict.items():
if v == value:
return k
print(k4v(edge_attributes, '5.3.1.9'))
## (604, 1037, 0)
The latter code, naively updated replacing iteritems with items, fails to return (604, 3936, 0), (1037, 3936, 0.
I looked up this question, because I wanted to know how to retrieve the name of "the key" if my dictionary only had one entry. In my case, the key was unknown to me and could be any number of things. Here is what I came up with:
dict1 = {'random_word': [1,2,3]}
key_name = str([key for key in dict1]).strip("'[]'")
print(key_name) # equal to 'random_word', type: string.
Try this:
def name_the_key(dict, key):
return key, dict[key]
mydict = {'key1':1, 'key2':2, 'key3':3}
key_name, value = name_the_key(mydict, 'key2')
print 'KEY NAME: %s' % key_name
print 'KEY VALUE: %s' % value
key_name = '...'
print "the key name is %s and its value is %s"%(key_name, mydic[key_name])
If you want to get the key of a single value, the following would help:
def get_key(b): # the value is passed to the function
for k, v in mydic.items():
if v.lower() == b.lower():
return k
In pythonic way:
c = next((x for x, y in mydic.items() if y.lower() == b.lower()), \
"Enter a valid 'Value'")
print(c)

Categories