appending values to dictionary in for loop - python

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.

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]

Sort the elements in dictionary based on its values and it should allow duplicates

# Sort the elements in dictionary based on its values
# without adding duplicates
dict1 = **{1:1, 2:9, 3:4, 4:6}**
sorted_values = sorted(dict1.values()) # Sort the values
sorted_dict = {}
for i in sorted_values:
for k in dict1.keys():
if dict1[k] == i:
sorted_dict[k] = dict1[k]
break
print(sorted_dict)
Output : **{1: 1, 3: 4, 4: 6, 2: 9}**
# with adding duplicates
# Sort the elements in dictionary based on its values
dict1 = **{0:6, 1:1, 2:9, 3:4, 4:6}**
sorted_values = sorted(dict1.values()) # Sort the values
sorted_dict = {}
for i in sorted_values:
for k in dict1.keys():
if dict1[k] == i:
sorted_dict[k] = dict1[k]
break
print(sorted_dict)
Output :
{1: 1, 3: 4, 0: 6, 2: 9}
here 4:6 is not printing
I have to print all values from dictionary even there are duplicates in a dictionary
What you do is terribly inefficient because you use 2 nested loops: an outer one on the values, then an inner one on the keys of the whole dictionary. It would be both simpler and most efficient to directly process the dictionary items and sort them according to the value:
sorted_items = sorted(dict1.items(), key=lambda x: x[1])
sorted_dict = dict(sorted_items)
with you 2nd example, it gives as expected:
{1: 1, 3: 4, 0: 6, 4: 6, 2: 9}
You can consider using an ordered dict for this.
>>> import operator
>>> from collections import OrderedDict
>>> dict1 = {1:1, 2:9, 3:4, 4:6}
>>> sorted_dict1 = sorted(dict1.items(), key=operator.itemgetter(1))
>>> dict2 = (OrderedDict(sorted_dict1))
>>> print(dict2)
OrderedDict([(1, 1), (3, 4), (4, 6), (2, 9)])
However, to have order and duplicates at the same time, tuples are a better solution.

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

using sort and set() on list values in dictionary

I have a dictionary which has single value as key and a list as the value. I am trying to go through the dictionary values and remove duplicates and sort the lists. Im using the below code to try this.
def activity_time_from_dict(adict):
for v in adict.values():
v = list(set(v))
v.sort()
From printing within the loop it seems to do it correctly, but if I look at the dictionary outside of the loop it has just been sorted and the duplicates remain. I want to replace the original list in the dictionary with the seted and sorted list. What am I doing wrong ?
Use slice assignment
v[:] = list(set(v))
# v[:] = set(v) has the same effect
to mutate the object and not just reassign the loop variable. Or more obviously, rebind to the same key:
for k in adict:
adict[k] = sorted(set(adict[k]))
In [1]: dd = {'a':[1, 3, -5, 2, 3, 1]}
In [2]: for i in dd:sorted(list(set(dd['a'])))
In [3]: for i in dd:
...: dd[i] = sorted(list(set(dd[i])))
...:
In [4]: dd
Out[4]: {'a': [-5, 1, 2, ]}
you can try this
def dict(adict):
for v in adict.values():
v = list(set(v))
v.sort()
return v
new_dict['your_key']=dict(old_dict)

Passing undefined value as argument to dictionary

How can I pass or send undefined value as an argument to dictionary? Consider this scenario:
Dict = {(1,'a'): 2, (1,''): 1, (1,'c'): 1, (3,'1'): 3};
print Dict [(1, pass)];
I want to get list of entries the dictionary which has first argument as 1.
Eg.
Dict [(1, pass)]
I want it to return:
{(1,'a'): 2, (1,''): 5, (1,'c'): 7}
How it can be done?
Regards
No need to pass anything other than the value you expect to be in the key, that is 1. You can construct a new dict, with the dictionary comprehension like this
my_dict = {(1,'a'): 2, (1,''): 1, (1,'c'): 1, (3,'1'): 3}
print {k: my_dict[k] for k in my_dict if 1 in k}
# {(1, 'c'): 1, (1, 'a'): 2, (1, ''): 1}
Note: pass is a statement in Python, which cannot be used in place of values. Perhaps you meant None.
Edit: If you know for sure that the value you are looking for will be in the first position always, you can do it like this (Thanks to #zhangxaochen :) )
print {k: my_dict[k] for k in my_dict if 1 == k[0]}
I would create a function to do that:
def filterFirst(a, Dict):
return {k: Dict[k] for k in Dict if k[0] == a}
You can also create a filter that filters on any index of the key-tuples:
def filterDictionary(a, Dict, index):
return {k: Dict[k] for k in Dict if k[index] == a}
Make sure that there are only tuples in the dictionary as keys.

Categories