Convert from pairs of list elements to adjacency list? - python

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])

Related

concatenating list of tuples python

I have a list of tuples as seen below :
l = [(1,'Nick'),(4,'George'),(4,'George'),(3,'Nick')]
what i would like to do is merge the tuples with the same Name and add the corresponding numbers.
Result here should be :
l_res = [(4,'Nick'),(8,'George')]
How could this be done using python?
You can use a combination of set and list comprehensions like this:
>>> l = [(1,'Nick'),(4,'George'),(4,'George'),(3,'Nick')]
>>> unique = set(e[1] for e in l)
>>> [(sum([x[0] for x in l if x[1] == n]), n) for n in unique]
[(8, 'George'), (4, 'Nick')]
You can use an intermediate set as suggested in a previous answer or with an intermediate dictionary like this:
l = [(1,'Nick'),(4,'George'),(4,'George'),(3,'Nick')]
d = dict()
for v, t in l:
d[t] = d.get(t, 0) + v
result = [(v, k) for k, v in d.items()]
print(result)
Output:
[(4, 'Nick'), (8, 'George')]
Probably the cleanest way is by using a Counter dictionary.
from collections import Counter
l = [(1,'Nick'),(4,'George'),(4,'George'),(3,'Nick')]
sum_dict = Counter()
for el in l:
sum_dict[el[1]] += el[0]
print(sum_dict) # Output: Counter({'George': 8, 'Nick': 4})
If you really want a list of tuples (which doesn't seem like the best datatype for this data), you can easily convert it with list comprehension over dict.items()
sum_list = [(v,k) for k,v in sum_dict.items()]
print(sum_list) # Output: [('Nick', 4), ('George', 8)]
You want to turn l_res into a dict by name, adding the numbers:
dic = {}
for tup in l:
num, name = tup
if name in dic:
dic[name] += num
else:
dic[name] = num
to turn it back into a list:
l_res = [(dic[k], k) for k in dic]

Python - how to sort a list of tuples to a dictionary or equivalent?

Hi i have a list of tuples containing words and their respective categories.
Is there anyway that i can clump them into something like a dictionary ?
Sample Data:
Data = [('word1 word2 word3', 2),
('word4 word5 word6', 3),
('word7 word8 word9', 3),
('word10 word11 word12', 2),
('word13 word14 word15', 1)]
Expected Output:
Out = {'1': 'word13 word14 word15'
'2': 'word1 word2 word3', 'word10 word11 word12'
'3': 'word4 word5 word6', 'word7 word8 word9'}
Is it possible to sort it in this manner ? what functions should i use. please advice me as i have a big amount of data. above is just an example. Thank You
The desired output you have shown is not exactly valid. To achieve the closest valid thing, use a defaultdict with an empty list
new_dict = defaultdict(list)
for values, key in Data:
new_dict[key].append(values)
Python can easily convert an iterable of (key, value) pairs into a dictionary, and back. But it looks like your tuples are (value, key).
This is still not that difficult in Python, just use a dict comprehension to switch them.
{k: v for v, k in Data}
Traditionally, dictionaries are unordered sets of key/value pairs, but dicts in recent Python versions can remember their insertion order. This is standard in Python 3.7, but considered an implementation detail before that in CPython 3.6. (And before that, you'd have to use an OrderedDict instead.)
So, if you really want your keys in order you can sort on them first, like so
import operator
{k: v for v, k in sorted(Data, key=operator.itemgetter(1))}
The sorted builtin can transform its elements before comparing them using a key function. The itemgetter(1) operator is equivalent to lambda xs: xs[1]. This is what makes it possible to sort tuples by their second element.
You can group data on categories and then use an OrderedDict
from itertools import groupby
from collections import OrderedDict
# Sort the data on the categories
Data = sorted(Data, key = lambda x : x[1])
# Group the data on basis of categories
grouped = [(key, list(i for i,j in group)) for key, group in groupby(Data, key=lambda x: x[1])]
# Put it into a OrderedDict, keys sorted
out = OrderedDict(grouped)
print(out[2]) # prints ['word1 word2 word3', 'word10 word11 word12']
You can use a defaultdict here and then from there use sorted with a dict() constructor to create the dictionary back in order you desire
from collections import defaultdict
dd = defaultdict(list)
for v, k in data:
dd[k].append(v)
d = dict(sorted(dd.items(), key=lambda x: x[0]))
print(d)
# {1: ['word13 word14 word15'], 2: ['word1 word2 word3', 'word10 word11 word12'], 3: ['word4 word5 word6', 'word7 word8 word9']}

appending values to dictionary in for loop

Just cant get this working. Any help is highly appreciated.
dict = {}
for n in n1:
if # condition #
dict[key] = []
dict[key].append(value)
print dict
This is printing something like this
{'k1':['v1']} and {'k1':['v2']}
I have few other nested for loops down this code, which will be using this dict and the dict has only the latest key value pairs i.e. {'k1':'v2'}
I am looking for something like {'k1':['v1','v2']}
Please suggest a solution without using setdefault
You can also check key existence before assign.
dict = {}
for n in n1:
if # condition #
if key not in dict:
dict[key] = []
dict[key].append(value)
print dict
Give collections.defaultdict a try:
#example below is in the docs.
from collections import defaultdict
s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
d = defaultdict(list)
for k, v in s:
d[k].append(v)
print(sorted(d.items()))
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
the d = defaultdict(list) line is setting the keys values to be an empty dictionary by default and appending the value to the list in the loop.
The problem with the code is it creates an empty list for 'key' each time the for loop runs. You need just one improvement in the code:
dict = {}
dict[key] = []
for n in n1:
if # condition #
dict[key].append(value)
print dict
a=[['a',1],['b',2],['c',1],['a',2],['b',3],['a',3]]
d={}
for i in a:
print (i)
if i[0] not in d:
d[i[0]]= [i[1]]
else:
d[i[0]].append(i[1])
print (d)
OP : {'a': [1, 2, 3], 'b': [2, 3], 'c': [1]}
You can use try except block in your loop.
another_dict = {}
for key, value in example_dict.items():
try:
another_dict[key].append(value)
except:
another_dict[key] = list(value)
Easy and clean.

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)]

Remove duplicate values from a defaultdict 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()

Categories