How can I get multiple shared items between two dictionaries in Python? - python

length_word = {'pen':3, 'bird':4, 'computer':8, 'mail':4}
count_word = {'pen':10, 'bird':50, 'computer':3, 'but':45, 'blackboard': 12, 'mail':12}
intersection = length_word.items() - count_word.items()
common_words = {intersection}
Err: TypeError: unhashable type: 'set'
I wish to get this dictionary:
outcome = {'pen':10, 'bird':50, 'computer':3, 'mail':12}
Thanks.

You should use .keys() instead of .items().
Here is a solution:
length_word = {'pen':3, 'bird':4, 'computer':8, 'mail':4}
count_word = {'pen':10, 'bird':50, 'computer':3, 'but':45, 'blackboard': 12, 'mail':12}
intersection = count_word.keys() & length_word.keys()
common_words = {i : count_word[i] for i in intersection}
#Output:
{'computer': 3, 'pen': 10, 'mail': 12, 'bird': 50}

intersection = count_word.keys() & length_word.keys()
outcome = dict((k, count_word[k]) for k in intersection)

try getting the intersection (common keys). one you have the common keys access those keys from the count_words.
res = {x: count_word.get(x, 0) for x in set(count_word).intersection(length_word)}
res:
{'bird': 50, 'pen': 10, 'computer': 3, 'mail': 12}

Just another dict comp:
outcome = {k: v for k, v in count_word.items() if k in length_word}

Using for loop check if the key is present in both the dictionary. If so then add that key, value pair to new dictionary.
length_word = {'pen':3, 'bird':4, 'computer':8, 'mail':4}
count_word = {'pen':10, 'bird':50, 'computer':3, 'but':45, 'blackboard': 12, 'mail':12}
my_dict = {}
for k, v in count_word.items():
if k in length_word.keys():
my_dict[k] = v
print(my_dict)

Related

how to remove dictionary element by outlier values Python

Suppose my dictionary contains > 100 elements and one or two elements have values different than other values; most values are the same (12 in the below example). How can I remove these a few elements?
Diction = {1:12,2:12,3:23,4:12,5:12,6:12,7:12,8:2}
I want a dictionary object:
Diction = {1:12,2:12,4:12,5:12,6:12,7:12}
It may be a bit slow because of the looping (especially as the size of the dictionary gets very large) and have to use numpy, but this will work
import numpy as np
Diction = {1:12,2:12,3:23,4:12,5:12,6:12,7:12,8:2}
dict_list = []
for x in Diction:
dict_list.append(Diction[x])
dict_array = np.array(dict_list)
unique, counts = np.unique(dict_array, return_counts=True)
most_common = unique[np.argmax(counts)]
new_Diction = {}
for x in Diction:
if Diction[x] == most_common:
new_Diction[x] = most_common
print(new_Diction)
Output
{1: 12, 2: 12, 4: 12, 5: 12, 6: 12, 7: 12}
d = {1:12,2:12,3:23,4:12,5:12,6:12,7:12,8:2}
new_d = {}
unique_values = []
unique_count = []
most_occurence = 0
# Find unique values
for k, v in d.items():
if v not in unique_values:
unique_values.append(v)
# Count their occurrences
def count(dict, unique_value):
count = 0
for k, v in d.items():
if v == unique_value:
count +=1
return count
for value in unique_values:
occurrences = count(d, value)
unique_count.append( (value, occurrences) )
# Find which value has most occurences
for occurrence in unique_count:
if occurrence[1] > most_occurence:
most_occurence = occurrence[0]
# Create new dict with keys of most occurred value
for k, v in d.items():
if v == most_occurence:
new_d[k] = v
print(new_d)
Nothing fancy, but direct to the point. There should be many ways to optimize this.
Output: {1: 12, 2: 12, 4: 12, 5: 12, 6: 12, 7: 12}

Merge random number of dicts in list

The task is to create a list of a random number of dicts (from 2 to 10)
dict's random numbers of keys should be letter, dict's values should
be a number (0-100), example: [{'a': 5, 'b': 7, 'g': 11}, {'a': 3, 'c': 35, 'g': 42}]
get a previously generated list of dicts and create one common dict:
if dicts have same key, we will take max value, and rename key with dict number with max value
if key is only in one dict - take it as is,
example: {'a_1': 5, 'b': 7, 'c': 35, 'g_2': 42}
I've written the following code:
from random import randint, choice
from string import ascii_lowercase
final_dict, indexes_dict = {}, {}
rand_list = [{choice(ascii_lowercase): randint(0, 100) for i in range(len(ascii_lowercase))} for j in range(randint(2, 10))]
for dictionary in rand_list:
for key, value in dictionary.items():
if key not in final_dict:
final_dict.update({key: value}) # add first occurrence
else:
if value < final_dict.get(key):
#TODO indexes_dict.update({:})
continue
else:
final_dict.update({key: value})
#TODO indexes_dict.update({:})
for key in indexes_dict:
final_dict[key + '_' + str(indexes_dict[key])] = final_dict.pop(key)
print(final_dict)
I only need to add some logic in order to keep indexes of final_dict values (created the separated dict for it).
I'm wondering if exists some more Pythonic way in order to solve such tasks.
This approach seems completely reasonable.
I, personally, would probably go around this way, however:
final_dict, tmp_dict = {}, {}
#Transform from list of dicts into dict of lists.
for dictionary in rand_list:
for k, v in dictionary.items():
tmp_dict.setdefault(k, []).append(v)
#Now choose only the biggest one
for k, v in tmp_dict.items():
if len(v) > 1:
final_dict[k+"_"+str(v.index(max(v))+1)] = max(v)
else: final_dict[k] = v[0]
You will need some auxiliary data structure to keep track of unrepeated keys. This uses collections.defaultdict and enumerate to aid the task:
from collections import defaultdict
def merge(dicts):
helper = defaultdict(lambda: [-1, -1, 0]) # key -> max, index_max, count
for i, d in enumerate(dicts, 1): # start indexing at 1
for k, v in d.items():
helper[k][2] += 1 # always increase count
if v > helper[k][0]:
helper[k][:2] = [v, i] # update max and index_max
# build result from helper data structure
result = {}
for k, (max_, index, count) in helper.items():
key = k if count == 1 else "{}_{}".format(k, index)
result[key] = max_
return result
>>> merge([{'a': 5, 'b': 7, 'g': 11}, {'a': 3, 'c': 35, 'g': 42}])
{'a_1': 5, 'b': 7, 'g_2': 42, 'c': 35}

Alter dictionary to map values to length of value

I have the following dictionary:
dict = {12:'Apples', 13:'Bananas', 14:'Oranges', 15:'Cherries'}
I want to rewrite this dictionary so that the values of dict become the keys of the new_dict. Then the values of new_dict will be the length of each new value, as follows:
new_dict = {'Apples':6, 'Bananas':7, 'Oranges':7, 'Cherries':8}
I am able to swap the values using
new_dict{}
for key,value in dict.items():
new_dict[key] = [value]
print(new_dict[key])
counts = len(new_dict[key])
But the len function here counts how many values are present, not how many characters per value.
You can do the following using a dictionary comprehension:
d = {12:'Apples', 13:'Bananas', 14:'Oranges', 15:'Cherries'}
d_new = {v: len(v) for v in d.values()}
Output:
>>> d_new
{'Apples': 6, 'Bananas': 7, 'Oranges': 7, 'Cherries': 8}
Note you should not use dict as a variable name as you overwrite the builtin dict class.
This is equivalent to the following for loop:
new_dict = {}
for v in d.values():
new_dict[v] = len(v)
You can use the dict function by zipping the values and the lengths:
d = {12:'Apples', 13:'Bananas', 14:'Oranges', 15:'Cherries'}
d_new = dict(zip(d.values(), map(len, d.values())))
Results
{'Apples': 6, 'Bananas': 7, 'Oranges': 7, 'Cherries': 8}

Convert python dict "key value" into dict having "k(value) ey"

I have a dict
d = {'A1BB11': 10,
'B1CC55': 20,
'A1A11': 30,
'A1A21': 40,
'B1HH21': 50,
'C1KK88': 60
}
I want to get a new dict from prev dict d
new_d = {'A1(80)':['BB11', 'A11', 'A21'],
'B1(70)':['CC55', 'HH21'],
'C1(60)':['KK88']
}
Could you provide a simple pythonic way to it? I am new to python world.
I think the simplest way would be to create two dictionaries to track the two values you're concerned with: the sums and the lists of suffixes.
from collections import defaultdict
d1, d2 = defaultdict(int), defaultdict(list)
d = {'A1BB11': 10,
'B1CC55': 20,
'A1A11': 30,
'A1A21': 40,
'B1HH21': 50,
'C1KK88': 60
}
for k, v in d.items():
prefix = k[:2]
d1[prefix] += v
d2[prefix].append(k[2:])
final = {'{}({})'.format(k, d1[k]): v for k, v in d2.items()}
print(final)
# {'A1(80)': ['BB11', 'A11', 'A21'],
# 'B1(70)': ['CC55', 'HH21'],
# 'C1(60)': ['KK88']}

Remove duplicates and combine multiple lists into one?

How do I remove duplicates and combine multiple lists into one like so:
function([["hello","me.txt"],["good","me.txt"],["good","money.txt"], ["rep", "money.txt"]]) should return exactly:
[["good", ["me.txt", "money.txt"]], ["hello", ["me.txt"]], ["rep", ["money.txt"]]]
The easiest one would be using defaultdict .
>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> for i,j in l:
d[i].append(j) #append value to the key
>>> d
=> defaultdict(<class 'list'>, {'hello': ['me.txt'], 'good': ['me.txt', 'money.txt'],
'rep': ['money.txt']})
#to get it in a list
>>> out = [ [key,d[key]] for key in d]
>>> out
=> [['hello', ['me.txt']], ['good', ['me.txt', 'money.txt']], ['rep', ['money.txt']]]
#driver values :
IN : l = [["hello","me.txt"],["good","me.txt"],["good","money.txt"], ["rep", "money.txt"]]
Try This ( no library needed ):
your_input_data = [ ["hello","me.txt"], ["good","me.txt"], ["good","me.txt"], ["good","money.txt"], ["rep", "money.txt"] ]
my_dict = {}
for box in your_input_data:
if box[0] in my_dict:
buffer_items = []
for items in box[1:]:
if items not in my_dict[box[0]]:
buffer_items.append(items)
remove_dup = list(set(buffer_items + my_dict[box[0]]))
my_dict[box[0]] = remove_dup
else:
buffer_items = []
for items in box[1:]:
buffer_items.append(items)
remove_dup = list(set(buffer_items))
my_dict[box[0]] = remove_dup
last_point = [[keys, values] for keys, values in my_dict.items()]
print(last_point)
Good Luck ...
You can do it with traditional dictionaries too.
In [30]: l1 = [["hello","me.txt"],["good","me.txt"],["good","money.txt"], ["rep", "money.txt"]]
In [31]: for i, j in l1:
...: if i not in d2:
...: d2[i] = j
...: else:
...: val = d2[i]
...: d2[i] = [val, j]
...:
In [32]: d2
Out[32]: {'good': ['me.txt', 'money.txt'], 'hello': 'me.txt', 'rep': 'money.txt'}
In [33]: out = [ [key,d1[key]] for key in d1]
In [34]: out
Out[34]:
[['rep', ['money.txt']],
['hello', ['me.txt']],
['good', ['me.txt', 'money.txt']]]
Let's first understand the actual problem :
Example Hint :
For these types of list problems there is a pattern :
So suppose you have a list :
a=[(2006,1),(2007,4),(2008,9),(2006,5)]
And you want to convert this to a dict as the first element of the tuple as key and second element of the tuple. something like :
{2008: [9], 2006: [5], 2007: [4]}
But there is a catch you also want that those keys which have different values but keys are same like (2006,1) and (2006,5) keys are same but values are different. you want that those values append with only one key so expected output :
{2008: [9], 2006: [1, 5], 2007: [4]}
for this type of problem we do something like this:
first create a new dict then we follow this pattern:
if item[0] not in new_dict:
new_dict[item[0]]=[item[1]]
else:
new_dict[item[0]].append(item[1])
So we first check if key is in new dict and if it already then add the value of duplicate key to its value:
full code:
a=[(2006,1),(2007,4),(2008,9),(2006,5)]
new_dict={}
for item in a:
if item[0] not in new_dict:
new_dict[item[0]]=[item[1]]
else:
new_dict[item[0]].append(item[1])
print(new_dict)
Your actual problem solution :
list_1=[["hello","me.txt"],["good","me.txt"],["good","money.txt"], ["rep", "money.txt"]]
no_dublicates={}
for item in list_1:
if item[0] not in no_dublicates:
no_dublicates[item[0]]=["".join(item[1:])]
else:
no_dublicates[item[0]].extend(item[1:])
list_result=[]
for key,value in no_dublicates.items():
list_result.append([key,value])
print(list_result)
output:
[['hello', ['me.txt']], ['rep', ['money.txt']], ['good', ['me.txt', 'money.txt']]]
yourList=[["hello","me.txt"],["good","me.txt"],["good","money.txt"], ["rep", "money.txt"]]
expectedList=[["good", ["me.txt", "money.txt"]], ["hello", ["me.txt"]], ["rep", ["money.txt"]]]
def getall(allsec, listKey, uniqlist):
if listKey not in uniqlist:
uniqlist.append(listKey)
return [listKey, [x[1] for x in allsec if x[0] == listKey]]
uniqlist=[]
result=sorted(list(filter(lambda x:x!=None, [getall(yourList,elem[0],uniqlist) for elem in yourList])))
print(result)
hope this helps
This can easily be solved using dict and sets.
def combine_duplicates(given_list):
data = {}
for element_1, element_2 in given_list:
data[element_1] = data.get(element_1, set()).add(element_2)
return [[k, list(v)] for k, v in data.items()]
Using Python to create a function that gives you the exact required output can be done as follows:
from collections import defaultdict
def function(data):
entries = defaultdict(list)
for k, v in data:
entries[k].append(v)
return sorted([k, v] for k, v in entries.items())
print(function([["hello","me.txt"],["good","me.txt"],["good","money.txt"], ["rep", "money.txt"]]))
The output is sorted before being returned as per your requirement. This would display the return from the function as:
[['good', ['me.txt', 'money.txt']], ['hello', ['me.txt']], ['rep', ['money.txt']]]
It also ensures that the keys are sorted. A dictionary is used to deal with the removal of duplicates (as keys need to be unique).
A defaultdict() is used to simplify the building of lists within the dictionary. The alternative would be to try and append a new value to an existing key, and if there is a KeyError exception, then add the new key instead as follows:
def function(data):
entries = {}
for k, v in data:
try:
entries[k].append(v)
except KeyError as e:
entries[k] = [v]
return sorted([k, v] for k, v in entries.items())
Create a empty array push the index 0 from childs arrays and join to convert all values to a string separate by space .
var your_input_data = [ ["hello","hi", "jel"], ["good"], ["good2","lo"], ["good3","lt","ahhahah"], ["rep", "nice","gr8", "job"] ];
var myprint = []
for(var i in your_input_data){
myprint.push(your_input_data[i][0]);
}
console.log(myprint.join(' '))

Categories