Remove duplicate values from a defaultdict python - python

I have a dictionary.
a = {6323: [169635, 169635, 169635], 6326: [169634,169634,169634,169634,169634,169634,169638,169638,169638,169638], 6425: [169636,169636,169636,169639,169639,169640]}
How do I remove the duplicate values for each key in dictionary a? And make the values become [value, occurrences]?
The output should be
b = {6323: [(169635, 3)], 6326: [(169634, 6), (19638, 4)], 6425: [(169636, 3), (19639, 2), (19640, 1)]}.
EDIT:
Sorry, I pasted the dict.items() output so they weren't dictionaries. I corrected it now.
Also edited the question to be more clear.

I would suggest iterating on the items and for each value build a defaultdict incrementing the occurence. Then convert that indo your tuple list (with the item method) and drop that in the output dictionnary.
b = {}
for k,v in a.items():
d = defaultdict(int)
for i in v:
d[i] += 1
b[k] = d.items()

Related

iterating over list-valued dictionary

Suppose I have a dictionary that has tuplets as keys and lists of tuples as values, for example:
d={(0,1):[(1,1)],
(0,2):[(1,1),(1,2)],
(0,3):[(1,1),(1,2),(1,3)]}
I would like to remove all entries such that their value is contained in the value of another key, for example:
from d I would like to remove the entry with key (0,1) because the (1,1) is contained in [(1,1),(1,2)]
and remove the entry with key (0,2) because [(1,1),(1,2)] is contained in [(1,1),(1,2),(1,3)].
Order of tuples in the lists matters.
I can solve this using a bunch of for loops, like this:
for key, val in d.items():
for k,v in d.items():
for i in range(0, len(val)):
if val[i] in v and len(v) - len(val) == 1:
del_me = True
else:
del_me = False
break
if del_me:
to_del.append(key)
for key in set(to_del):
del d[key]
edit: (further explanation)
Keys are not important here but will be important later.
In other words:
let a,b,c,d denote unique tuples
let k1,k2,..., denote keys
lets have the entries:
k1:[a],
k2:[d],
k3:[a,b],
k4:[b,a],
k5:[a,b,c],
I want to end up with:
k2,k4,k5
Removed entries will be:
k1 because a is in k3
k3 because a,b is in k5
It hurts my eyes when I'm looking at this, sorry.
What would be a pythonic way to do this?
Let's say that you have an dictionary that looks like as follows:
d={(0,1):[(1,1)],(0,2):[(1,1),(1,2)],(0,3):[(1,1),(1,2),(1,3)],(0,4):[(1,1),(1,2),(1,4)]}
Now you want to compare the values against all the keys with one another. I suggest you place all the values in this dictionary in a list.
mylist=[]
for key in d.keys():
mylist.append(d[key])
print(mylist)
mylist will look like as follows having all the values of the dictionary.
[[(1, 1)], [(1, 1), (1, 2)], [(1, 1), (1, 2), (1, 3)], [(1, 1), (1, 2), (1, 4)]]
Now you want to compare all these values with one another and remove those values that are the subsets of any of those values. Like in this example, [(1,1)] is the subset of [(1,1),(1,2)] and so [(1,1)] will be removed. Similarly, [(1,1),(1,2)] is the subset of [(1,1),(1,2),(1,3)] and so it will also be removed. We can accomplish this as follows:
out = []
for k, elm in enumerate(mylist):
for _,elm2 in enumerate(mylist[:k] + mylist[k + 1:]):
if frozenset(elm).issubset(elm2):
break
else:
out.append(elm)
print(out)
out list will give us unique elements of the list mylist.
[[(1, 1), (1, 2), (1, 3)], [(1, 1), (1, 2), (1, 4)]]
In the above segment of code, we loop over the list and take the current index. Then we loop again over the same list but we remove the element at the current index of the first loop. Then we convert the first element of the index of the first loop into a frozenset and use the method issubset in order to check if the first element if a subset of the second element or not.
Now we just compare our dictionary d values with out list. And if, d values are not in out list we delete that key from the dictionary d. This is accomplished as follows:
for key in list(d):
if d[key] not in out:
del d[key]
print(d)
Th output dictionary d will be:
{(0, 3): [(1, 1), (1, 2), (1, 3)], (0, 4): [(1, 1), (1, 2), (1, 4)]}

Convert from pairs of list elements to adjacency list?

Is it possible to convert from a list of pair of elements like this:
s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
to an adjacency list like this below:
{'yellow':['1', '3'], 'blue':['2','4'], 'red':['1']}
Use a defaultdict:
from collections import defaultdict
d = defaultdict(list)
for k, v in s:
d[k].append(v)
This will allow you to append items to the lists (elements of the dictionary) as if they were there, and if they are not, they will be created as empty lists for you.
This is not doing anything that could not also be done more manually with:
d = {}
for k, v in s:
if k not in d:
d[k] = []
d[k].append(v)
Note: if you really want the elements of these lists to be strings, then do:
d[k].append(str(v))
Use the groupby function. Mind that you have to sort the list first.
You can do like:
m = {}
for key, value in s:
m.setdefault(key, []).append(value)
print(m)
I've found the answer, thanks
result = {}
for i in follower_list:
result.setdefault(i[0], []).append(i[1])

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

How do I combine a dictionary key (tuple) and its value together into one string?

I currently have the dictionary:
matrix = {(0, 0): 1, (1, 1): 1, (2, 2): 1}
And I need to create a single string that displays:
(0,0,1),(1,1,1),(2,2,1)
How can I join the dictionary keys (tuples) and value together into one string?
I was thinking of putting the keys into a list and adding the key into the list, but I am not entirely sure how to add it in the right order given that tuples are immutable.
result = []
for i, j in matrix.items():
result.append(i)
for i in result:
The basic operation you're looking for is:
[k + (v,) for k, v in matrix.items()]
To print that in your specific way, you probably want:
print(', '.join(str(k + (v,)) for k, v in matrix.items()))
Note that dictionaries are unordered, so the order of the result is undefined.
Your approach will keep them in the right order. The only thing it looks like you need to change in your code is splitting the tuple into its sub-parts:
>>> result = []
>>> for (x, y), z in matrix.items():
result.append((x, y, z))
>>> print result
[(0, 0, 1), (1, 1, 1), (2, 2, 1)]
I don't know whether this is the most pythonic solution but try this:
str(tuple(_ + (matrix[_],) for _ in matrix))
Or use %s:
print(','.join(["(%s,%s,%s)"%(*k,v) for k,v in matrix.items()]))
Or:
print(','.join([str((*k,v)) for k,v in matrix.items()]))
Or if version not above python 3.5:
print(','.join(["(%s,%s,%s)"%k+(v,) for k,v in matrix.items()]))
Or:
print(','.join([str(k+(v,)) for k,v in matrix.items()]))
Building off your work so far:
lst = []
for i,j in matrix.items():
lst.append((i[0],i[1],j))
result = ",".join( repr(e) for e in lst )
Please note that your keys are tuples which are immutable so cannot be modified, so you need to unpack them first and then join with the dictionary value.
You can use,
matrix = {(0, 0): 1, (1, 1): 1, (2, 2): 1}
# *k unpack keys
print(','.join("({},{},{})".format(*k,v) for k,v in matrix.items()))
# output,
# (0,0,1),(1,1,1),(2,2,1)

How to unpack a dictionary of list (of dictionaries!) and return as grouped tuples?

I have a data structure consisting of mixed dictionaries and lists. I am trying to unpack this so as to get tuples of the keys and all sub-values for each key.
I am working with list comprehensions, but just not getting it to work. Where am I going wrong?
I saw many other answers about unpacking a list-of-lists (e.g. 1,2), but could not find an example where a single key unpacks against multiple sub-values.
desired output --> [('A',1,2),('B',3,4)]
actual output --> [('A',1), ('A',2), ('B',3), ('B',4)]
code:
dict_of_lists = {'A':[{'x':1},{'x':2}], 'B':[{'x':3},{'x':4}] }
print [(key,subdict[subkey],) for key in dict_of_lists.keys() for subdict in dict_of_lists[key] for subkey in subdict.keys()]
When list comprehensions become
long
unclear/hard to read
and most importantly, do not work
ditch them and go with the manual for loop(s) every time:
Python 2.x
def unpack(d):
for k, v in d.iteritems():
tmp = []
for subdict in v:
for _, val in subdict.iteritems():
tmp.append(val)
yield (k, tmp[0], tmp[1])
print list(unpack({'A':[{'x':1},{'x':2}], 'B':[{'x':3},{'x':4}] }))
Python 3.x
def unpack(d):
for k, v in d.items():
tmp = []
for subdict in v:
for _, val in subdict.items():
tmp.append(val)
yield (k, *tmp) # stared expression used to unpack iterables were
# not created yet in Python 2.x
print(list(unpack({'A':[{'x':1},{'x':2}], 'B':[{'x':3},{'x':4}] })))
Output:
[('A', 1, 2), ('B', 3, 4)]
Loop through the list of dicts and get only the values. Then combine with the dict key.
>>> for k,L in dict_of_lists.iteritems():
... print tuple( [k]+[v for d in L for v in d.values()])
('A', 1, 2)
('B', 3, 4)
If you need a one liner:
>>> map(tuple, ([k]+[v for d in L for v in d.values()] for k,L in dict_of_lists.iteritems()))
[('A', 1, 2), ('B', 3, 4)]

Categories