Suppose I have a list such as
L = ['B0','B1','C1','C2','D1','D3']
Then How do I split the list into values and keys and store it in a dictionary in the following form:-
{ 'B':['0','1'],
'C':['1','2'],
'D':['1','3']}
L = ['B0','B1','C1','C2','D1','D3']
d = {}
for i in L:
d.setdefault(i[0], []).append(i[1])
>>> d
{'B': ['0', '1'], 'C': ['1', '2'], 'D': ['1', '3']}
You can iterate over the list and break each string element to create a dictionary. Try this:
from collections import defaultdict
l = ['B0','B1','C1','C2','D1','D3']
d = defaultdict(list)
for key, value in l:
d[key].append(value)
print d
Related
I am having multiple lists and I need to compare each list with one another and return the name of lists which are different. We need to consider value of elements in list irrespective of their position while comparing lists.
For example:-
Lis1=['1','2','3']
Lis2=['1','2']
Lis3=['0','1','3']
Lis4=[]
Lis5=['1','2']
Output:-
['Lis1','Lis2','Lis3','Lis4']
Thanks in advance.
Try this:
input_lists = {"Lis1": ['1', '2', '3'], "Lis2": ['1', '2'],
"Lis3": ['0', '1', '3'], "Lis4": [], "Lis5": ['1', '2']}
output_lists = {}
for k, v in input_lists.items():
if sorted(v) not in output_lists.values():
output_lists[k] = sorted(v)
unique_keys = list(output_lists.keys())
print(unique_keys) # ['Lis1', 'Lis2', 'Lis3', 'Lis4']
import itertools
Lis1=['1','2','3']
Lis2=['1','2']
Lis3=['0','1','3']
Lis4=[]
Lis5=['1','2']
k=[Lis1,Lis2,Lis3,Lis4,Lis5]
k.sort()
list(k for k,_ in itertools.groupby(k))
output
[[], ['0', '1', '3'], ['1', '2'], ['1', '2', '3']]
a simple way to implement
Lis1=['1','2','3']
Lis2=['1','2']
Lis3=['0','1','3']
Lis4=[]
Lis5=['1','2']
lis=[Lis1,Lis2,Lis3,Lis4,Lis5]
final=[]
for ele in lis:
if(ele not in final):
final.append(ele)
print(final)
with your given data you can use:
Lis1=['1','2','3']
Lis2=['1','2']
Lis3=['0','1','3']
Lis4=[]
Lis5=['1','2']
name_lis = {'Lis1': Lis1, 'Lis2': Lis2, 'Lis3': Lis3, 'Lis4': Lis4, 'Lis5': Lis5}
tmp = set()
response = []
for k, v in name_lis.items():
s = ''.join(sorted(v))
if s not in tmp:
tmp.add(s)
response.append(k)
print(response)
output:
['Lis1', 'Lis2', 'Lis3', 'Lis4']
name_lis dictionary contains the name of your list and the actual list, you are iterating over each list, and for each list, you are sorting the elements and then converting in a string, if the string was encountered before you know that the list is a duplicate if not you are adding the list to the response
Poked around but couldn't figure it out, probably a very simple solution but please help me understand.
Source (sample.txt):
1,1,2,3
2,3,2,4,4
This:
import csv
from collections import defaultdict
input = "sample.txt"
with open(input) as f:
r = csv.reader(f)
d = defaultdict(list)
rlabel = 1
for row in r:
d[rlabel].append(row)
rlabel += 1
print(d)
Gets This:
defaultdict(<class 'list'>, {1: [['1', '1', '2', '3']], 2: [['2', '3', '2', '4', '4']]})
Why are there double brackets around my lists?
Why are there double brackets around my lists?
Your code works exactly as expected. The key point is the usage of extend and append.
append adds the parameter you passed as a single element. Due to a list is an object and your defaultdict class is list, so the list is appended as a list of lists.
extend method iterate in the input and extend the original list by adding all elements from an iterable.
So, in this case, if you want to add a single list to your defaultdict you should use list.extend method. And your output will be:
defaultdict(<class 'list'>, {1: ['1', '1', '2', '3'], 2: ['2', '3', '2', '4', '4']})
With a defaultdict, when a key is created a default value is associated to it
>>> d = defaultdict(list)
>>> 'a' in d[1]
False
>>> d
defaultdict(<class 'list'>, {1: []})
Given that your row is a list, you are appending a list to the list associated with the key.
To add the elements you can do
d[rlabel]+= row
This question already has answers here:
How can one make a dictionary with duplicate keys in Python?
(9 answers)
Closed 6 months ago.
Good day all,
I am trying to convert a list of length-2 items to a dictionary using the below:
my_list = ["b4", "c3", "c5"]
my_dict = {key: value for (key, value) in my_list}
The issue is that when a key occurrence is more than one in the list, only the last key and its value are kept.
So in this case instead of
my_dict = {'c': '3', 'c': '5', 'b': '4'}
I get
my_dict = {'c': '5', 'b': '4'}
How can I keep all key:value pairs even if there are duplicate keys.
Thanks
For one key in a dictionary you can only store one value.
You can chose to have the value as a list.
{'b': ['4'], 'c': ['3', '5']}
following code will do that for you :
new_dict = {}
for (key, value) in my_list:
if key in new_dict:
new_dict[key].append(value)
else:
new_dict[key] = [value]
print(new_dict)
# output: {'b': ['4'], 'c': ['3', '5']}
Same thing can be done with setdefault. Thanks #Aadit M Shah for pointing it out
new_dict = {}
for (key, value) in my_list:
new_dict.setdefault(key, []).append(value)
print(new_dict)
# output: {'b': ['4'], 'c': ['3', '5']}
Same thing can be done with defaultdict. Thanks #MMF for pointing it out.
from collections import defaultdict
new_dict = defaultdict(list)
for (key, value) in my_list:
new_dict[key].append(value)
print(new_dict)
# output: defaultdict(<class 'list'>, {'b': ['4'], 'c': ['3', '5']})
you can also chose to store the value as a list of dictionaries:
[{'b': '4'}, {'c': '3'}, {'c': '5'}]
following code will do that for you
new_list = [{key: value} for (key, value) in my_list]
If you don't care about the O(n^2) asymptotic behaviour you can use a dict comprehension including a list comprehension:
>>> {key: [i[1] for i in my_list if i[0] == key] for (key, value) in my_list}
{'b': ['4'], 'c': ['3', '5']}
or the iteration_utilities.groupedby function (which might be even faster than using collections.defaultdict):
>>> from iteration_utilities import groupedby
>>> from operator import itemgetter
>>> groupedby(my_list, key=itemgetter(0), keep=itemgetter(1))
{'b': ['4'], 'c': ['3', '5']}
You can use defaultdict to avoid checking if a key is in the dictionnary or not :
from collections import defaultdict
my_dict = defaultdict(list)
for k, v in my_list:
my_dict[k].append(v)
Output :
defaultdict(list, {'b': ['4'], 'c': ['3', '5']})
How would I, in a function, create a dictionary who's keys are a given dictionary's values, and vice versa, where the given dictionary has multiple values per key?
For example, given a dictionary:
d = {"1":["a","b"],"2":["b","a","c"],"3":["c","d"]}
I'd need to return a dictionary like:
d2 = {"a":["1","2"],"b":["1","2"],"c":["2","3"],"d":["3"]}
My only idea was to make a list of all values, then manually check each key for each value, but I couldn't figure out how to do that without knowing the number of keys and values. Any help would be vastly appreciated.
Try:
{letter: [key for key in d if letter in d[key]] for letter in set(letter for key in d for letter in d[key])}
Explanation: set(letter for key in d for letter in d[key]) is a set of all letters that appears in the original dict. Then we make a new dict, in which every entry is letter: [key for key in d if letter in d[key]], which means one of the letters, mapping to a list of numbers that mapped to it in the original dict.
Easy using collections.defaultdict() which defaults as list
loop on the sorted key/value couple
inner loop on the value items
for each value item, create/update list with original dict key
code:
import collections
d3 = collections.defaultdict(list)
for k,v in sorted(d.items()):
for vi in v:
d3[vi].append(k) # create list or append to existing list
print(dict(d3))
result:
{'b': ['1', '2'], 'd': ['3'], 'c': ['2', '3'], 'a': ['1', '2']}
data = [(key, value) for key, values in d.items() for value in values]
d2 = defaultdict(list)
for value, key in data:
d2[key].append(value)
print(key, value)
Here is a solution I found 5 years ago
from operator import itemgetter
from itertools import groupby
d = {'1': ['a', 'c'],'2': ['a', 'b', 'c'], '3': ['b']}
d2 = {x: [t[1] for t in group] for (x, group) in groupby(sorted(((j, k) for k, v in d.items() for j in v), key=itemgetter(0)), key=itemgetter(0))}
# {'a': ['1', '2'], 'c': ['1', '2'], 'b': ['2', '3']}
I have the following dic:
dic = {'shape': ['a', 'b', 'c'], 'item1_item2_item3': ['1_2_3', '5_6_10', '3_7_9']}
I want to convert it to:
dic = {'shape': ['a', 'b', 'c'], 'item1': ['1', '2', '3'], 'item2': ['5', '6', '10'], 'item3': ['3', '7', '9']}
Basically, I want to split based on '_' and make new keys/values out of the original key and its values.
The size of the second key might have more items; for example 'item1_item2,item3,item4'.
Use zip() to pair up the split key and values; you'll want to build a new dictionary here:
new = {}
for key, value in dic.items():
if '_' not in key:
new[key] = value
continue
for new_key, new_value in zip(key.split('_'), value):
new[new_key] = new_value.split('_')
You could mash this in to a dictionary comprehension but it becomes rather harder to follow:
{nk: (nv.split('_') if '_' in k else v)
for k, v in dic.items() for nk, nv in zip(k.split('_'), v)}
Demo:
>>> dic = {'shape': ['a', 'b', 'c'], 'item1_item2_item3': ['1_2_3', '5_6_10', '3_7_9']}
>>> new = {}
>>> for key, value in dic.items():
... if '_' not in key:
... new[key] = value
... continue
... for new_key, new_value in zip(key.split('_'), value):
... new[new_key] = new_value.split('_')
...
>>> new
{'item2': ['5', '6', '10'], 'item3': ['3', '7', '9'], 'shape': ['a', 'b', 'c'], 'item1': ['1', '2', '3']}
>>> {nk: (nv.split('_') if '_' in k else v)
... for k, v in dic.items() for nk, nv in zip(k.split('_'), v)}
{'item2': ['5', '6', '10'], 'item3': ['3', '7', '9'], 'shape': ['a', 'b', 'c'], 'item1': ['1', '2', '3']}
What you wanna do it's this:
Extract the key that you wanna split
split it and assign it to a new list
assing the values of the key to a list of the new list and append it to the new key
delete the old key and value
To get you started
dic = {item: "whatever", item1_item2_item3: [1,2,3], [2,3,4]. [4,5,6]}
copy = dic[item1_item2_item3]
name = item1_item2_item3
name = name.split("_")
#this make a list like this: [item1, item2, item3]
for i in len(name):
dic[name[i]] = copy[i]
del.dic[item1_item2_item3]
You can split string using my_string.split("_") to get a list strings. Here's one solution to split the strings and the keys and assign the new values:
dic = {'shape': ['a', 'b', 'c'], 'item1_item2_item3': ['1_2_3', '5_6_10', '3_7_9']}
new_dic = {}
for k in dic.keys():
val = dic[k]
subkeys = k.split("_")
if len(subkeys) > 1:
for s in range(len(subkeys)):
subkey = subkeys[s]
subvals = val[s].split("_")
new_dic[subkey] = subvals
# this handles the case where the key has no underscores
else:
new_dic[k] = val
print new_dic