Finding all the common and sub common values in a dictionary - python

I am new in using dicitonaries in python. I have a simple Problem at Hand. I have dicrionary named "Input".
Input={'VAR1':['K1','K2','K3','K4','K5...'],
'VAR2':['K3','K4',...],
'VAR3':['K2','K4','K5',...]}
The number of keys in the dictionary "Input" can vary. The Output i desire is to get a list of all common values and i want to get Sub common values as a dictionary
'K4' string common in all the lists (for all key values)
'K3' is only present in the list with key'VAR1' and 'VAR2'.
So it helps if i have the corresponding keys
Output:
Common_Value=['K4',....]
Subcommon_Values1=['VAR1':['K3....'],'VAR2':['K3....']]
Subcommon_values2=['VAR1':['K5',...],'VAR3':['K5',....]]
Can anyone help me with this?
Thank you

This will get you all of the common values:
sect = None
for k,v in Input.items():
if sect == None:
sect = set( v )
else:
sect = sect.intersection( set(v) )
Common_Value = list( sect )
Until you make clear what the difference between your different SubCommonValues results are, and their actual structure (you seem to have keys in lists), can't be sure this is what you want or not:
all = None
for k,v in Input.items():
if all == None:
all = set( v )
else:
all = all.union( set(v) )
diff = all.difference( sect )
uncom = { x:list() for x in diff }
for x in diff:
for k,v in Input.items():
if x in v:
uncom[x].append(k)
grps = {}
for k,v in uncom.items():
kv = tuple(v)
if kv not in grps:
grps[kv] = [k]
else:
grps[kv].append(k)
for k,v in grps.items():
print({ x:v for x in k })

you can do something like :
result=[i for i in Input if "K4" in Input[i]]
Example :
>>> Input={'VAR1':['K1','K2','K3','K4','K5'],'VAR2':['K3','K5'],'VAR3':['K2','K4','K5']}
>>> result=[i for i in Input if "K4" in Input[i]]
>>> result
['VAR1', 'VAR3']
EDIT :
maybe something like :
commonValues=['K4', 'K2']
result=[i for i in Input if set(commonValues).issubset(set(Input[i]))]
this will return the list of key in your Input dict that contain all element of the commonValues list...

Related

How could I create a dictionary taking specific strings of elements of a list?

I have a list with elements that contain values separated by "_" and I need to take the 4th as the values and the 5 and 6th as keys of a dictionary
My list:
['MLID_D_08_NGS_34_H08.fsa',
'MLID_D_17_W2205770_Michael_Jordan_A10.fsa',
'MLID_D_18_W2205770_Michael_Jordan_B10.fsa',
'MLID_D_19_W2205768_Maradona_Guti_C10.fsa',
'MLID_D_20_W2205768_Maradona_Guti_D10.fsa',
'MLID_D_38_No_DNA_F12.fsa']
I am trying to get a dictionary like this
thisdict = {
"34_H08": "NGS",
"Michael_Jordan_A10": "W2205770",
"Michael_Jordan_B10": "W2205770",
...
"DNA_F12": "No",
}
Optimised way of creating same dictionary
thisdict = dict(
(lambda x: ('_'.join(x[4:6]), x[3]))(s.split('_'))
for s in lst
)
Using reduce function
reduce(lambda x, y: x.update({ '_'.join(y.split('_')[4:6]): y.split('_')[3] }) or x, lst, {})
Try this:
lst = ['MLID_D_08_NGS_34_H08.fsa',
'MLID_D_17_W2205770_Michael_Jordan_A10.fsa',
'MLID_D_18_W2205770_Michael_Jordan_B10.fsa',
'MLID_D_19_W2205768_Maradona_Guti_C10.fsa',
'MLID_D_20_W2205768_Maradona_Guti_D10.fsa',
'MLID_D_38_No_DNA_F12.fsa']
dic = {}
for name in lst:
name = name.split(".")[0].split("_")
dic["_".join(name[4:])] = name[3]
print(dic)
This code may help you.
lst = ['MLID_D_08_NGS_34_H08.fsa',
'MLID_D_17_W2205770_Michael_Jordan_A10.fsa',
'MLID_D_18_W2205770_Michael_Jordan_B10.fsa',
'MLID_D_19_W2205768_Maradona_Guti_C10.fsa',
'MLID_D_20_W2205768_Maradona_Guti_D10.fsa',
'MLID_D_38_No_DNA_F12.fsa']
lst = [a.split('.') for a in lst] # split by .
dict_ = {}
for l in lst:
k = '_'.join(l[0].split('_')[4:]) # make key
v = l[0].split('_')[3] # make value
dict_[k]=v # add value to dict
print(dict_)
OUTPUT
{'34_H08': 'NGS',
'Michael_Jordan_A10': 'W2205770',
'Michael_Jordan_B10': 'W2205770',
'Maradona_Guti_C10': 'W2205768',
'Maradona_Guti_D10': 'W2205768',
'DNA_F12': 'No'}
As #matszwecja indicated s.split('_') is the way to go.
You can access different parts of the split as follows:
lst = ['MLID_D_08_NGS_34_H08.fsa',
'MLID_D_17_W2205770_Michael_Jordan_A10.fsa',
'MLID_D_18_W2205770_Michael_Jordan_B10.fsa',
'MLID_D_19_W2205768_Maradona_Guti_C10.fsa',
'MLID_D_20_W2205768_Maradona_Guti_D10.fsa',
'MLID_D_38_No_DNA_F12.fsa']
thisdict = {s.split('_')[4] + '_' + s.split('_')[5].split('.')[0]: s.split('_')[3] for s in lst}

How can I update all entries of a dictionary in Python with certain logic?

I have a dictionary with key value pairs of a persons name with a list of domain names like so
dictionary = {
'Trent':['help.google.com', 'smooth.google.com', 'bob.google.com'],
'Bill':['help.google.com', 'smooth.google.com', 'bob.google.com', 'trent.awesome.net']}
I want to make it so that in the dictionary, there is only the parent domain (instead of smooth.google.com it's just google.com). Ordinarily, with a regular list I'll use code like this get the parent domain names:
domains = ['help.google.com', 'smooth.google.com', 'bob.google.com', 'trent.awesome.net']
parents = []
for domain in domains:
parents.append(domain[domain.index('.') + 1:])
Now I'm trying to combine that logic with logic that makes sure that in the dictionary, among values no matter the key, there are no duplicates using Counter and list comprehension. That code is this:
cnt = Counter()
for idx in result.values():
cnt.update(idx)
res = {idx: [key for key in j if cnt[key] == 1]
for idx, j in result.items()}
When I try to combine the logic, the BEST I'll get is an empty list next to the name. Using the above example of a dictionary the result will be
'Trent':[]
I tried using two for loops like so:
cnt = Counter()
for idx in result.values():
for x in idx:
x = x[x.index('.') + 1:]
cnt.update(idx)
res = {idx: [key for key in j if cnt[key] == 1]
for idx, j in result.items()}
Any help is greatly appreciated. I hope I've provided sufficient detail in my question.
This script will filter out domains in the list and keeps only parent domains:
dictionary = {
'Trent':['help.google.com', 'smooth.google.com', 'bob.google.com'],
'Bill':['help.google.com', 'smooth.google.com', 'bob.google.com', 'trent.awesome.net']}
out = {k: [*set(vv.split('.', maxsplit=1)[-1] for vv in v)] for k, v in dictionary.items()}
print(out)
Prints:
{'Trent': ['google.com'], 'Bill': ['google.com', 'awesome.net']}
EDIT: To filter out the duplicities across every key, you can use this:
out, seen = {}, set()
for k, v in dictionary.items():
for vv in v:
domain = vv.split('.', maxsplit=1)[-1]
if domain not in seen:
out.setdefault(k, []).append(domain)
seen.add(domain)
print(out)
Prints:
{'Trent': ['google.com'], 'Bill': ['awesome.net']}

Reversing the key values in a dictionary (advanced reverse string in Python)

So what I was trying to do was output the string "33k22k11k", which is just the last value followed by the reversed last key followed by the second last value followed by the second last reversed key and so on. I'm not sure how to get the reversed key value for the specific loop that I am in. From the code I currently I have, I get the output:
dict = {"k1":1, "k2":2, "k3":3}
current=""
current_k=""
for k,v in dict.items():
for i in k:
current_k=i+current_k
current=str(v)+current_k+current
print(current)
print(current_k)
33k2k1k22k1k11k
3k2k1k
Edited
First of all, if you are on python < 3.6, dict does not keep the order of items. You might want to use collections.OrderedDict for your purpose.
d = {"k1":1, "k2":2, "k3":3}
d.keys()
# dict_keys(['k2', 'k1', 'k3'])
whereas,
d = OrderedDict()
d['k1'] = 1
d['k2'] = 2
d['k3'] = 3
d.keys()
# odict_keys(['k1', 'k2', 'k3'])
With our new d, you can either add the key and values and reverse it:
res = ''
for k, v in d.items():
res += str(k) + str(v)
res[::-1]
# '33k22k11k'
or reversely iterate:
res = ''
for k, v in reversed(d.items()):
res += str(v)[::-1] + str(k)[::-1]
res
# '33k22k11k'
I may be wrong but it seems like you would want to reset the value of current_k each time you access a new key
dict = {"k1":1, "k2":2, "k3":3}
current=""
for k,v in dict.items():
current_k=""
for i in k:
current_k=i+current_k
current=str(v)+current_k+current
print(current)
print(current_k)
Why not simply do:
print(''.join([a+str(b) for a,b in dict.items()])[::-1])
Output:
"33k22k11k"
But if the values are different from the keys, do:
print(''.join([str(b)[::-1]+a for a,b in dict.items()[::-1]]))
You can use the Python map function to create the reversed string(using f-string) for each key/value pair and then join it.
dict1 = {"k1":1, "k2":2, "k3":3}
new_dict = "".join(map(lambda k, v: f'{k}{v}'[::-1] , dict1.keys(), dict1.values()))
Output:
33k22k11k
You can do something like this perhaps:
dict = {"k1":1, "k2":2, "k3":3}
print("".join(list(reversed([str(v)+"".join(reversed(k)) for k, v in dict.items()]))))
Output:
33k22k11k

Change Keys in dictionary

I have a dictionary:
d = {1:[9,9,9],2:[8,8,8],3:[7,7,7]}
and a list of keys :
newkeylist = [4,2,3]
Now i want check the keys in the dict with the content in the list. If they are different i want to replace the key in the dict with the one in the list.
for i in range(len(newkeylist)):
if d.key()[i] != newkeylist[i]:
d.key()[i] = newkeylist[i]
try something like this
d = {1:[9,9,9],2:[8,8,8],3:[7,7,7]}
newkeylist = [4,2,3]
d_copy = d.copy()
for i, (k, v) in enumerate(d_copy.items()):
if k != newkeylist[i]:
d[newkeylist[i]] = v
del d[k]
but as #jonrsharpe said, it's not an ordered dict: the output is random

Combine Python dictionaries that have the same Key name

I have two separate Python List that have common key names in their respective dictionary. The second list called recordList has multiple dictionaries with the same key name that I want to append the first list clientList. Here are examples lists:
clientList = [{'client1': ['c1','f1']}, {'client2': ['c2','f2']}]
recordList = [{'client1': {'rec_1':['t1','s1']}}, {'client1': {'rec_2':['t2','s2']}}]
So the end result would be something like this so the records are now in a new list of multiple dictionaries within the clientList.
clientList = [{'client1': [['c1','f1'], [{'rec_1':['t1','s1']},{'rec_2':['t2','s2']}]]}, {'client2': [['c2','f2']]}]
Seems simple enough but I'm struggling to find a way to iterate both of these dictionaries using variables to find where they match.
When you are sure, that the key names are equal in both dictionaries:
clientlist = dict([(k, [clientList[k], recordlist[k]]) for k in clientList])
like here:
>>> a = {1:1,2:2,3:3}
>>> b = {1:11,2:12,3:13}
>>> c = dict([(k,[a[k],b[k]]) for k in a])
>>> c
{1: [1, 11], 2: [2, 12], 3: [3, 13]}
Assuming you want a list of values that correspond to each key in the two lists, try this as a start:
from pprint import pprint
clientList = [{'client1': ['c1','f1']}, {'client2': ['c2','f2']}]
recordList = [{'client1': {'rec_1':['t1','s1']}}, {'client1': {'rec_2':['t2','s2']}}]
clientList.extend(recordList)
outputList = {}
for rec in clientList:
k = rec.keys()[0]
v = rec.values()[0]
if k in outputList:
outputList[k].append(v)
else:
outputList[k] = [v,]
pprint(outputList)
It will produce this:
{'client1': [['c1', 'f1'], {'rec_1': ['t1', 's1']}, {'rec_2': ['t2', 's2']}],
'client2': [['c2', 'f2']]}
This could work but I am not sure I understand the rules of your data structure.
# join all the dicts for better lookup and update
clientDict = {}
for d in clientList:
for k, v in d.items():
clientDict[k] = clientDict.get(k, []) + v
recordDict = {}
for d in recordList:
for k, v in d.items():
recordDict[k] = recordDict.get(k, []) + [v]
for k, v in recordDict.items():
clientDict[k] = [clientDict[k]] + v
# I don't know why you need a list of one-key dicts but here it is
clientList = [dict([(k, v)]) for k, v in clientDict.items()]
With the sample data you provided this gives the result you wanted, hope it helps.

Categories

Resources