Python Dictionaries: making the key:value the key and appending new values - python

EDIT: My question has been getting a lot of follow up questions because on the surface, it doesn't appear to make any sense. For most people, dictionaries are an illogical way to solve this problem. I agree, and have been frustrated by my constraints (explained in the comments). In my scenario, the original KV pairs are going to be encoded as data to be read by another server using the ObjectID. This, however, must be fed into an encoding function as a dictionary. The order does not matter, but the KV pairs must be given a new unique value. The original KV pairs will end up as a new string key in this new dictionary with the ObjectID as a new unique value.
Keep in mind that I am using Python 2.7.
The Issue
Note that this is a matter of presenting a dictionary (dictA), encoded by the ObjectID values, within the constraints of what I have been given
I have a dictionary, say dictA = {'a':'10', 'b':'20', 'c':'30'}, and I have a list of ObjectIdentifier('n'), where n is a number. What is the best way to create dictB so that dictB is a new dictionary with the key equal to dictA's key:value pair and the value equal to the corresponding ObjectIdentifier('n') in the list.
The new dictB should be:
{"'a':'10'":ObjectIdentifier('n'), "'b':'20'":ObjectIdentifier('n+1'), "'c':'30'":ObjectIdentifier('n+2')}
If that makes any sense.

The problem is that dictionaries aren't ordered. So you say
dictA = {'a':'10', 'b':'20', 'c':'30'}
but as far as python knows it could be
dictA = {'c':'30', 'a':'10', 'b':'20'}
Because dictionaries don't have order.
You could create your dict like this:
result = {key: ObjectIdentifier(n+pos) for pos, key in enumerate(dictA.items())}
But there is no way to determine which key will fall in which position, because, as I said, dictionaries don't have order.
If you want alphabetic order, just use sorted()
result = {key: ObjectIdentifier(n+pos)
for pos, key in enumerate(sorted(dictA.items()))}

I don't know why you would want this
def ObjectIdentifier(n):
print(n)
return "ObjectIdentifier("+ str(n) + ")"
dictA = {'a':'10', 'b':'20', 'c':'30'}
dictB = {}
for n, key in enumerate(sorted(dictA.keys())):
dictB[key] = {dictA[key] : ObjectIdentifier(str(n))}
Output:
{'a': {'10': 'ObjectIdentifier(0)'}, 'b': {'20': 'ObjectIdentifier(1)'}, 'c': {'30': 'ObjectIdentifier(2)'}}

Related

Getting keys and values of dictionary if key in list

So I have a dictionary names "ngrams_count". I want to find all keys in this dictionary that are in a list called "words_to_find". I would also like to return the values associated with those keys.
So far, this is what I'm working with
ideasrep = [key for key in words_to_find if key in ngrams_count]
That returns only the keys that are found in the word list.
I'm also looking for a way to return only the key/values pairs for which the value is greater than one. I've tried a similar technique as this:
[(key,values) for key, values in ngrams_count.items() if values > 1]
However, this only seems to work if I stay within the dictionary and I'm running out of ideas... Ideally, I'd like a way to do these two things simultaneously.
Your first version is almost right, you just need to add ngrams_count[key] to the result.
ideasrep = [(key, ngrams_count[key]) for key in words_to_find if key in ngrams_count]
Or you can use the second version, but change the condition to check if the key is in words_to_find.
[(key,values) for key, values in ngrams_count.items() if key in words_to_find]
If words_to_find is big, you should convert it to a set before the list comprehension to make the second version more efficient.

Dictionaries with lists as values: how to retrieve the key given one value

I have a Python dictionary which looks like this:
alphabetic_dict = {
'a':['apple', 'ant', 'atlas'],
'b':['bee', 'beer','bat'],
'c':['car', 'cash', 'computer']
}
What I want to do is, given one of the values within a list, print the corresponding key. For example, if I write car, I want my program to output something like That value corresponds to 'c'. It might seem a silly thing, but I've never worked with a dictionary containing lists as values, so I'm very confused.
Search the value (which is a list) for the thing you;re looking for
for k, v in alphabetic_dict.items()
if 'car' in v:
print k
input = 'c'
for key, values in alphabetic_dict.items():
if input in values:
print(f'That value corresponds to {key}')
This uses f-strings which were introduced in python 3.6

How to retain an item in python dictionary? [duplicate]

This question already has answers here:
Extract a subset of key-value pairs from dictionary?
(14 answers)
Closed 6 years ago.
I've a dictionary my_dict and a list of tokens my_tok as shown:
my_dict = {'tutor': 3,
'useful': 1,
'weather': 1,
'workshop': 3,
'thankful': 1,
'puppy': 1}
my_tok = ['workshop',
'puppy']
Is it possible to retain in my_dict, only the values present in my_tok rather than popping the rest?
i.e., I need to retain only workshop and puppy.
Thanks in advance!
Just overwrite it like so:
my_dict = {k:v for k, v in my_dict.items() if k in my_tok}
This is a dictionary comprehension that recreates my_dict using only the keys that are present as entries in the my_tok list.
As said in the comments, if the number of elemenst in the my_tok list is small compaired to the dictionary keys, this solution is not the most efficient one. In that case it would be much better to iterate through the my_tok list instead as follows:
my_dict = {k:my_dict.get(k, default=None) for k in my_tok}
which is more or less what the other answers propose. The only difference is the use of .get dictionary method with allows us not to care whether the key is present in the dictionary or not. If it isn't it would be assigned the default value.
Going over the values from the my_tok, and get the results that are within the original dictionary.
my_dict = {i:my_dict[i] for i in my_tok}
Create a new copy
You can simply overwrite the original dictionary:
new_dic = {token:my_dict[key] for key in my_tok if key in my_dict}
Mind however that you construct a new dictionary (perhaps you immediately writ it to my_dict) but this has implications: other references to the dictionary will not reflect this change.
Since the number of tokens (my_tok) are limited, it is probably better to iterate over these tokens and do a contains-check on the dictionary (instead of looping over the tuples in the original dictionary).
Update the original dictionary
Given you want to let the changes reflect in your original dictionary, you can in a second step you can .clear() the original dictionary and .update() it accordingly:
new_dic = {token:my_dict[key] for key in my_tok if key in my_dict}
my_dict.clear()
my_dict.update(new_dic)

Python Dedup/Merge List of Dicts

Say that I have a list of dicts:
list = [{'name':'john','age':'28','location':'hawaii','gender':'male'},
{'name':'john','age':'32','location':'colorado','gender':'male'},
{'name':'john','age':'32','location':'colorado','gender':'male'},
{'name':'parker','age':'24','location':'new york','gender':'male'}]
In this dict, 'name' can be considered a unique identifier. My goal is to not only dedup this list for identical dicts (ie list[1] and list[2], but to also merge/append differing values for a single 'name' (ie list[0] and list[1/2]. In other words, I want to merge all of the 'name'='john' dicts in my example to a single dict, like so:
dedup_list = [{'name':'john','age':'28; 32','location':'hawaii; colorado','gender':'male'},
{'name':'parker','age':'24','location':'new york','gender':'male'} ]
I have tried thus far to create my second list, dedup_list, and to iterate through the first list. If the 'name' key does not already exist in one of dedup_list's dicts, I will append it. It is the merging part where I am stuck.
for dict in list:
for new_dict in dedup_list:
if dict['name'] in new_dict:
# MERGE OTHER DICT FIELDS HERE
else:
dedup_list.append(dict) # This will create duplicate values as it iterates through each row of the dedup_list. I can throw them in a set later to remove?
My list of dicts will never contain more than 100 items, so an O(n^2) solution is definitely acceptable but not necessarily ideal. This dedup_list will eventually be written to a CSV, so if there is a solution involving that, I am all ears.
Thanks!
well, I was about to craft a solution around defaultdict, but hopefully #hivert posted the best solution I could came with, which is in this answer:
from collections import defaultdict
dicts = [{'a':1, 'b':2, 'c':3},
{'a':1, 'd':2, 'c':'foo'},
{'e':57, 'c':3} ]
super_dict = defaultdict(set) # uses set to avoid duplicates
for d in dicts:
for k, v in d.iteritems():
super_dict[k].add(v)
i.e. I'm voting for closing this question as a dupe of that question.
N.B.: you won't be getting values such as '28; 32', but instead get a set containing [28,32], which then can be processed into a csv file as you wish.
N.B.2: to write the csv file, have a look at the DictWriter class

Python: Tool to compare pairs of dicts of varying deepness?

I have a couple of pairs of rather big dicts. The structure of the pair dicts is exactly the same but the values will differ. All pairs differ in how nested they are.
To clarify:
dict_a has same structure as dict_b
dict_c has same structure as dict_d (but is different from dict_a and dict_b)
etc.
Is there a tool out there that makes it easy to implement a function to compare the values only, and/or do some basic arithmetic on them? My dicts can be quite nested, so a simple [for k,v in dict_x.iteritems()...] won't do.
Sounds like a problem for...recursive functions!
Basically, if I understand your question, you have a deep dictionary with varying levels of depths at unspecified keys. You'd like to compare the values of dict_a to dict_b but don't care much about the keys: just the differences in values. Here's an idea using a recursive function to print out each set of values that doesn't match.
def dict_compare(da, db):
for k, v in da.iteritems():
if isinstance(v, dict): #if the value is another dict:
dict_compare(v, db[k]) #enter into the comparison function again!
else:
if v != db[k]:
print 'values not equal at', k
Then you just can call
dict_compare(dict_a, dict_b)
The magic being that if the value of a given key is in fact another dictionary, just call your comparison function again.
Obviously, if you wanted to do something more complicated than just print the simple key of the values that don't match, just modify what happens after the if v != db[k] line.

Categories