Iterating through two dictionaries - python

I have two dictionaries:
dict_1 = {'H1':[0,1,3,2],
'H2':[5,4,2,1,5],
'H3':[1,2,5]}
dict_2 = {'H1':[[1,4,3,2],
[6,5,3,2],
[1,4,3,2]],
'H2':[[0,0,1,6,3],
[2,1,4,2,1],
[5,1,2,5,3]],
'H3':[[2,3,4],
[2,1,4],
[0,1,2]]}
I'm trying to iterate through the items in the values of the keys in dict_1, and check if any of those items are in any of the items in the values of the corresponding key in dict_2. Then print the value, and the index where it was found in the key of dict_2.
So for example, because 0 in the list of the key 'H1' of dict_1 isn't found in any of the lists of the key 'H1' in dict 2, nothing would be printed. Now if we check for 1, then
1, 'H1', 0, # because there is a one in the first list of 'H1' of dict_2
1, 'H1', 2, # because there is a one in the 3rd list of 'H1' of dict_2
here 1 corresponds to the item that was checked for, 'H1' the key that was checked, and 0, and 2 represent which list the 1 was found in in dict_2
this is what I have:
for i in range(3):
for k,v in dict_1.items():
for x,y in dict_2.items():
if k == x:
for j in v:
if j in y[i]:
print j,x,i
But I'm wondering if this will take care of everything, or if it will print repeated items?

This should work:
for key, d1_list in dict_1.iteritems():
for element in d1_list:
for ind, d2_list in enumerate(dict_2[key]):
if element in d2_list:
print element, key, ind
Iterate over all the key, and lists and d1. Then over element in d1_list, and finally check if it's any any of the lists in dict_2 corresponding to the same key.

Some answers first: yes, your code will "take care of everything", and will not "print repeated items" meaning that if a value is appearing several time in the same list in dict_2, than it will be spotted only once by your code.
Executing your code on those dict demonstrates this:
dict_1 = {'H1':[0,1,3,2]}
dict_2 = {'H1':[[0,0],
[1,2]]}
for i in range(2):
for k,v in dict_1.items():
for x,y in dict_2.items():
if k == x:
for j in v:
if j in y[i]:
print j,x,i
Output is:
0 H1 0
1 H1 1
2 H1 1
Hence spotting only once the 0 value while appearing twice in first sublist in dict_2.
Now, to complete the same objective, we can simplify a little your code, given that:
you want to compare only the same keys in the two dicts
you may want to have different size of list in dict_2
I would propose the following:
# Loop on all key values in dict_1
for k,v in dict_1.items():
# Loop only on values in dict_2 for same key
for i,y in enumerate(dict_2[k]):
# Loop over values in first list
for j in v:
# Assert existence in second list
if j in y:
# Display result if found (note that index of subblist in dict_2 is retrieved through enumerate function
print j,x,i
This output the exact same result with additional lisibility and flexibility for dict_2 format.
Hope this helps.

Related

Iteratively adding new lists as values to a dictionary

I have created a dictionary (dict1) which is not empty and contains keys with corresponding lists as their values. I want to create a new dictionary (dict2) in which new lists modified by some criterion should be stored as values with the corresponding keys from the original dictionary. However, when trying to add the newly created list (list1) during every loop iteratively to the dictionary (dict2) the stored values are empty lists.
dict1 = {"key1" : [-0.04819, 0.07311, -0.09809, 0.14818, 0.19835],
"key2" : [0.039984, 0.0492105, 0.059342, -0.0703545, -0.082233],
"key3" : [0.779843, 0.791255, 0.802576, 0.813777, 0.823134]}
dict2 = {}
list1 = []
for key in dict1:
if (index + 1 < len(dict1[key]) and index - 1 >= 0):
for index, element in enumerate(dict1[key]):
if element - dict1[key][index+1] > 0:
list1.append(element)
dict2['{}'.format(key)] = list1
list.clear()
print(dict2)
The output I want:
dict2 = {"key1" : [0.07311, 0.14818, 0.19835],
"key2" : [0.039984, 0.0492105, 0.059342],
"key3" : [0.779843, 0.791255, 0.802576, 0.813777, 0.823134]}
The problem is that list always refers to the same list, which you empty by calling clear. Therefore all values in the dict refer to the same empty list object in memory.
>>> # ... running your example ...
>>> [id(v) for v in dict2.values()]
[2111145975936, 2111145975936, 2111145975936]
It looks like you want to filter out negative elements from the values in dict1. A simple dict-comprehension will do the job.
>>> dict2 = {k: [x for x in v if x > 0] for k, v in dict1.items()}
>>> dict2
{'key1': [0.07311, 0.14818, 0.19835],
'key2': [0.039984, 0.0492105, 0.059342],
'key3': [0.779843, 0.791255, 0.802576, 0.813777, 0.823134]}
#timgeb gives a great solution which simplifies your code to a dictionary comprehension but doesn't show how to fix your existing code. As he says there, you are reusing the same list on each iteration of the for loop. So to fix your code, you just need to create a new list on each iteration instead:
for key in dict1:
my_list = []
# the rest of the code is the same, expect you don't need to call clear()

Deleting multiple key value pairs from dictionary in python

I generated a python dictionary for all the duplicate images in a folder. The python dictonary now contains values in the following format:
{
"image_1.jpg": ['image_xyz.jpg', 'image_abc.jpg'],
"image_xyz.jpg": ["image_1.jpg", "image_abc.jpg"],
"image_abc.jpg": ["image_xyz.jpg","image_1.jpg"],
"image_2.jpg": ["image_3.jpg"],
"image_3.jpg": ["image_2.jpg"],
"image_5.jpg": []
}
Each key, value pair thus appears atleast twice in the list. Empty list for keys are present which have no duplicates.
Is there a way to delete all the duplicate key value pairs present? so that the dictionary looks like the following:
{
"image_1.jpg": ['image_xyz.jpg', 'image_abc.jpg'],
"image_2.jpg": ["image_3.jpg"],
"image_5.jpg": []
}
I tried using list to first store all the values from the key value pair and then deleting them from the dictionary but it empties the whole dictionary.
source = {
"image_1.jpg": ['image_xyz.jpg', 'image_abc.jpg'],
"image_xyz.jpg": ["image_1.jpg", "image_abc.jpg"],
"image_abc.jpg": ["image_xyz.jpg","image_1.jpg"],
"image_2.jpg": ["image_3.jpg"],
"image_3.jpg": ["image_2.jpg"],
"image_5.jpg": []
}
dest = dict()
for k,v in source.items():
ok = True
for k1,v1 in dest.items():
if k in v1: ok = False
if ok: dest[k] = v
print(dest) # New filtered dict
I usually do this method when getting rid of duplicates in a list:
First put all the values in a matrix / 2 dimensional list including the key, so the first 3 values would be like this:
{
"image_1.jpg": ['image_xyz.jpg', 'image_abc.jpg'],
"image_xyz.jpg": ["image_1.jpg", "image_abc.jpg"],
"image_abc.jpg": ["image_xyz.jpg","image_1.jpg"],
}
would turn into:
List=[
["image_1.jpg","image_xyz.jpg","image_abc.jpg"],
["image_xyz.jpg","image_1.jpg","image_abc"],
["image_abc.jpg","image_xyz.jpg","image_1.jpg"]
]
make sure the keys are all in the 0th position so that you can save them.
keys=[x[0] for x in List]
then sort the list:
sorted_list=[sorted(x) for x in List]
then simply compare them using an if statement in a nested for loop and if a list is equal to another then delete it:
for i in sorted_list:
for j,k in enumerate(sorted_list):
if i==k:
del sorted_list[j] # deleting any equal lists
now that the duplicates are gone and you have the keys convert the list back into a dictionary if preferred
Overall code if needed:
List=[
["image_1.jpg","image_xyz.jpg","image_abc.jpg"],
["image_xyz.jpg","image_1.jpg","image_abc"],
["image_abc.jpg","image_xyz.jpg","image_1.jpg"]
]
keys=[x[0] for x in List]
sorted_list=[sorted(x) for x in List]
for i in sorted_list:
for j,k in enumerate(sorted_list):
if i==k:
del sorted_list[j] # deleting any equal lists

How to check if tuple key contains an element in dictionary

I am looking for an operation that could do something similar to this:
dict[ ( tuple[0] , _ ) ]
The dictionary contains tuples as keys.
How do I check if the dictionary contains a value where the tuple key has a specific value as the first part and any value as the second part?
Try this,
#Dictionary with tuples as keys
dict_with_tup = dict([((1,2),3), ((1,4),2), ((2,5),7)])
#value that you wanna find (just the first value of the tuple)
x = 1
#filtered dict based on that value
{k:v for k,v in dict_with_tup.items() if k[0]==x}
{(1, 2): 3, (1, 4): 2}
for a dictionary d
x = # value of interest
for key in d.keys():
if key[0] == x:
#do stuff
but as khelwood noted in the comments, it's not a very efficient way of doing things

Iterate over dict from value to value

I have a dictionary like this :
data = {1: [u'-', u's'], 2: [u'je', u'co', u'na'], ...}
The KEY is the LENGTH of the words that belong to it. I want to call a function (that will count levenshtein distance) for words that are longer than X and shorter than Y. How would I do it ?
The main problem is getting the dictionary length because len() returns the number of items in the dictionary, not keys.
Now I am doing it like this:
for k in data:
if k >= len(word)-distance and k <= len(word)+distance:
for item in data[k]:
if levenshtein(word, item) == distance:
words.append(item)
return words
data.keys() will give you the keys, you can iterate over them.
You can get a list of all words with length between X and Y with
sum((words for key, words in data.items() if X<key<Y), [])

Finding if there are distinct elements in a python dictionary

I have a python dictionary containing n key-value pairs, out of which n-1 values are identical and 1 is not. I need to find the key of the distinct element.
For example: consider a python list [{a:1},{b:1},{c:2},{d:1}]. I need the to get 'c' as the output.
I can use a for loop to compare consecutive elements and then use two more for loops to compare those elements with the other elements. But is there a more efficient way to go about it or perhaps a built-in function which I am unaware of?
If you have a dictionary you can quickly check and find the first value which is different from the next two values cycling around the keys of your dictionary.
Here's an example:
def find_different(d):
k = d.keys()
for i in xrange(0, len(k)):
if d[k[i]] != d[k[(i+1)%len(k)]] and d[k[i]] != d[k[(i+2)%len(k)]]:
return k[i]
>>> mydict = {'a':1, 'b':1, 'c':2, 'd':1}
>>> find_different(mydict)
'c'
Otherwise, if what you have is a list of single-key dictionaries, then you can do it quite nicely mapping your list with a function which "extracts" the values from your elements, then check each one using the same logic.
Here's another working example:
def find_different(l):
mask = map(lambda x: x[x.keys()[0]], l)
for i in xrange(0, len(l)):
if mask[i] != mask[(i+1)%len(l)] and mask[i] != mask[(i+2)%len(l)]:
return l[i].keys()[0]
>>> mylist = [{'a':1},{'b':1},{'c':2},{'d':1}]
>>> find_different(mylist)
'c'
NOTE: these solutions do not work in Python 3 as the map function doesn't return a list and neither does the .keys() method of dictionaries.
Assuming that your "list of pairs" (actually list of dictionaries, sigh) cannot be changed:
from collections import defaultdict
def get_pair(d):
return (d.keys()[0], d.values()[0])
def extract_unique(l):
d = defaultdict(list)
for key, value in map(get_pair, l):
d[value].append(key)
return filter(lambda (v,l): len(l) == 1, d.items())[0][1]
If you already have your dictionary, then you make a list of all of the keys: key_list = yourDic.keys(). Using that list, you can then loop through your dictionary. This is easier if you know one of the values, but below I assume that you do not.
yourDic = {'a':1, 'b':4, 'c':1, 'd':1, }
key_list = yourDic.keys()
previous_value = yourDic[key_list[0]] # Making it so loop gets past first test
count = 0
for key in key_list:
test_value = yourDic[key]
if (test_value != previous_value) and count == 1: # Checks first key
print key_list[count - 1]
break
elif (test_value != previous_value):
print key
break
else:
previous_value = test_value
count += 1
So, once you find the value that is different, it will print the key. If you want it to print the value, too, you just need a print test_value statement

Categories