Python: how to converet list of list into a dictionary - python

I am trying to converet the list of list into a dictionary using defaultdict method.
I have a list of list:
a= [[1,2],[2,3,4], [4,5,6], [3,7], [6,10]]
I want the output in this format:
{1: [0], 2: [0], 2: [1], 3: [1], 4: [1], 4: [2], 5: [2], 6: [2], 3: [3], 7: [3], 6: [4], 10: [4]})
Here is my code:
a =[[1,2],[2,3,4], [4,5,6], [3,7], [6,10]]
clusters = defaultdict(list)
cluster_sz = {}
cliques = []
cluster_idx = 0
for clique in a:
cliques.append(clique)
for v in clique:
clusters[v].append(cluster_idx)
cluster_idx+=1
print(clusters)
The output of this code is:
{1: [0], 2: [0,1], 3: [1,3], 4: [1, 2], 5: [2], 6: [2, 4], 7: [3], 10: [4]})
But I need this type of output:
{1: [0], 2: [0], 2: [1], 3: [1], 4: [1], 4: [2], 5: [2], 6: [2], 3: [3], 7: [3], 6: [4], 10: [4]})

You can try with this approach
So instead of dictionary with overlapping keys, you can create list of dictionaries.
a= [[1,2],[2,3,4], [4,5,6], [3,7], [6,10]]
b = [{r:i} for i,k in enumerate(a) for r in k ]
[{1: 0}, {2: 0}, {2: 1}, {3: 1}, {4: 1}, {4: 2}, {5: 2}, {6: 2}, {3: 3}, {7: 3}, {6: 4}, {10: 4}]

Here is a shortened code with your desired output.
a = [[1,2],[2,3,4], [4,5,6], [3,7], [6,10]]
d = {}
for i, sublist in enumerate(a):
for num in sublist:
if num not in d:
d[num] = []
d[num].append(i)
print(d)

dict = {1: [0], 2: [0,1], 3: [1,3], 4: [1, 2], 5: [2], 6: [2, 4], 7: [3], 10: [4]}
convertedDict = {}
for (i, j) in dict.items():
if len(j) > 1:
for k in j:
convertedDict[i] = [k]
else:
convertedDict[i] = j
print (convertedDict)
{1: [0], 2: [1], 3: [3], 4: [2], 5: [2], 6: [4], 7: [3], 10: [4]}
Those object, have duplicated keys, thats the reason, why, converted dict saving only last value in last iteration.
https://thispointer.com/can-a-dictionary-have-duplicate-keys-in-python/

Related

how can I add an element to a nested dictionary [duplicate]

This question already has answers here:
How do I initialize a dictionary of empty lists in Python?
(7 answers)
Closed last month.
here's my code:
import copy
teamdict = {1:{},2:{},3:{},4:{},5:{}}
teamlst = []
matchlst = [1,2,3,4,5]
lst = [[1,5,0],[1,0,3],[2,3,0],[2,0,1],[3,0,6],[3,0,1],[4,0,1],[4,0,5],[5,0,8]]
for i in matchlst:
for j in lst:
if i == j[0]:
teamlst.append(j[2])
elif len(teamlst)>0 and i != j:
continue
else:
pass
teamlst = set(teamlst)
teamlst = list(teamlst)
teamlst.sort()
team_dictionary = dict.fromkeys(teamlst, [])
teamdict[i] = team_dictionary
teamlst.clear()
print(teamdict)
dic = copy.deepcopy(teamdict)
for i in lst:
dic[i[0]][i[2]].append(i[1])
print(dic)
this is what i got:
{1: {0: [5, 0], 3: [5, 0]}, 2: {0: [3, 0], 1: [3, 0]}, 3: {1: [0, 0], 6: [0, 0]}, 4: {1: [0, 0], 5: [0, 0]}, 5: {8: [0]}}
but what i expect is:
{1: {0: [5], 3: [0]}, 2: {0: [3], 1: [0]}, 3: {1: [0], 6: [0]}, 4: {1: [0], 5: [0]}, 5: {8: [0]}}
what goes wrong?
seems like this append method add the element to all the keys in the nested dictionary
I assume you have created your dictionary with multiple references to the same list.
If I execute your code I get what you want.
>>> lst = [[1,5,0],[1,0,3],[2,3,0],[2,0,1],[3,0,6],[3,0,1],[4,0,1],[4,0,5],[5,0,8]]
>>> dic = {1: {0: [], 3: []}, 2: {0: [], 1: []}, 3: {1: [], 6: []}, 4: {1: [], 5: []}, 5: {8: []}}
>>> for i in lst:
... dic[i[0]][i[2]].append(i[1])
...
>>> print(dic)
{1: {0: [5], 3: [0]}, 2: {0: [3], 1: [0]}, 3: {1: [0], 6: [0]}, 4: {1: [0], 5: [0]}, 5: {8: [0]}}

Why does the list not save the elements?

while(True):
size,times = map(int,input().split())
v=list(map(int,input().split()))
store=dict()
for i in range(size):
store[v[i]]=list()
store[v[i]].append(i+1)
print(store)
while(times>0):
pos,num = map(int,input().split())
For example:
size=8 (input array size) times=4
pos=1 (The position of num in list start by 1) num=3
{1: [1]}
{1: [1], 3: [2]}
{1: [1], 3: [2], 2: [3]}
{1: [1], 3: [2], 2: [4]}
{1: [1], 3: [2], 2: [4], 4: [5]}
{1: [1], 3: [6], 2: [4], 4: [5]}
{1: [1], 3: [6], 2: [7], 4: [5]}
{1: [8], 3: [6], 2: [7], 4: [5]}
Things I want:
{1: [1]}
{1: [1], 3: [2]}
{1: [1], 3: [2], 2: [3]}
{1: [1], 3: [2], 2: [3,4]}
{1: [1], 3: [2], 2: [3,4], 4: [5]}
{1: [1], 3: [2,6], 2: [4], 4: [5]}
{1: [1], 3: [2,6], 2: [3,4,7], 4: [5]}
{1: [1,8], 3: [2,6], 2: [3,4,7], 4: [5]}
This line store[v[i]]=list() is creating a new list every time
remove it and change the next append line to:
store.setdefault(v[i], list()).append(i+1)
That will create the list only if it doesn't exist.
Alternatively use collections.defaultdict(list)

Turn Dictionary of Sets into Dictionary of Lists

Given the Dictionary of Sets:
{1: {2}, 2: {1, 3, 5}, 3: {2, 4}, 4: {3, 7}, 5: {2, 6}, 6: {5}, 7: {8, 4}, 8: {7}}
Is there anyway I can easily turn it into a Dictionary of Lists?
Desired Output:
{1: [2], 2: [1, 3, 5], 3: [2, 4], 4: [3, 7], 5: [2, 6], 6: [5], 7: [8, 4], 8: [7]}
result = {key: list(values) for key, values in dictionary.items()}
Use dict comprehension and convert set to list using the list() function
a = {1: {2}, 2: {1, 3, 5}, 3: {2, 4}, 4: {3, 7}, 5: {2, 6}, 6: {5}, 7: {8, 4}, 8: {7}}
{k:list(v) for k,v in a.items()}
Out[274]:
{1: [2],
2: [1, 3, 5],
3: [2, 4],
4: [3, 7],
5: [2, 6],
6: [5],
7: [8, 4],
8: [7]}

Accessing tuple values in a dict

q = "cats dogs"
d = {'cats': {1: 1, 2: 3, 3: 1, 4: 1}, 'nuts': {3: 1}, 'egg': {5: 1, 6: 2}, 'dogs': {1: 8, 2: 2, 3: 4}, 'idea': {4: 1}, 'frog': {2: 1, 4: 1, 5: 1}}
newList = []
for word in q:
for x,y in d.values():
newList.append(d[word].x())
What I'm attempting to do here is get each first part of the number pairs and put into the list when it corresponds to a word in q. So I'm expecting newList to be [1,2,3,4,1,2,3].
I am getting ValueError: too many values to unpack (expected 2). How should I be doing this?
The values in the dictionary 'd' are actually of type dictionary themselves, not tuples. I think you may want to reorganize this a bit.
for word in q.split(" "):
if word in d:
child_dict = d[word]
for key in child_dict:
newList.append(key)
Is this what you're looking for?
q = "cats dogs"
d = {'cats': {1: 1, 2: 3, 3: 1, 4: 1}, 'nuts': {3: 1}, 'egg': {5: 1, 6: 2}, 'dogs': {1: 8, 2: 2, 3: 4}, 'idea': {4: 1}, 'frog': {2: 1, 4: 1, 5: 1}}
newList = []
for word in q.split(' '):
newList.extend(list(d[word].keys()))
print(newList)
It prints out [1, 2, 3, 4, 1, 2, 3]
q = "cats dogs"
d = {'cats': {1: 1, 2: 3, 3: 1, 4: 1}, 'nuts': {3: 1}, 'egg': {5: 1, 6: 2}, 'dogs': {1: 8, 2: 2, 3: 4}, 'idea': {4: 1}, 'frog': {2: 1, 4: 1, 5: 1}}
newList = []
for word in q.split(' '):
if word in d:
newList.extend([i for i in d[word]])
print(newList)

Merging hierarchy of dictionaries in Python

I have two dictionaries, and what I'm trying to do is a bit odd. Basically, I want to merge them. That's simple enough. But they're hierarchies of of dictionaries, and I want to merge them in such a way that if an item in a dictionary is itself a dictionary and exists in both, I want to merge those dictionaries as well. If it's not a dictionary, I want the values from the second dictionary to overwrite the values from the first one. Something sort of like this:
a = {0: {0: "a"},
1: [0, 1, 2]}
b = {0: {1: "b"},
1: [3, 4, 5]}
Merge(a, b)
#output:
{0: {0: "a",
1: "b"},
1: [3, 4, 5]}
Does that make sense? Because the key "0" contained a dictionary in both a and b, it merged those dictionaries as well. But in the case of the second key, it was a list so it just overwrote it.
So I suppose I'll be looking at some kind of recursive function? Not quite sure how to approach this one.
Thanks!
Edit: I forgot to mention one pretty crucial detail:
I need a function that works in both 2.6.2 and 2.7.3.
Assuming you might have nested dictionaries (based on your thinking in terms of recursion), something like this should work,
from copy import deepcopy
def merge(a, b):
if isinstance(b, dict) and isinstance(a, dict):
a_and_b = a.viewkeys() & b.viewkeys()
every_key = a.viewkeys() | b.viewkeys()
return {k: merge(a[k], b[k]) if k in a_and_b else
deepcopy(a[k] if k in a else b[k]) for k in every_key}
return deepcopy(b)
The return value of merge(a, b) is conceptually like creating a (deep) copy of a and running a recursive version of a.update(b).
Using some nested examples,
a = {0: {0: 'a'},
1: [0, 1, 2],
2: [9, 9],
3: {'a': {1: 1, 2: 2}, 'b': [0, 1]}}
b = {0: {1: 'b'},
1: [3, 4, 5],
2: {22: 22, 33: 33},
3: {'a': {2: 22, 3: 33}, 'b': [99, 88]}}
merge(a, b) produces,
{0: {0: 'a', 1: 'b'},
1: [3, 4, 5],
2: {22: 22, 33: 33},
3: {'a': {1: 1, 2: 22, 3: 33}, 'b': [99, 88]}}
EDIT: Python 2.6 version
def merge(a, b):
if isinstance(b, dict) and isinstance(a, dict):
a_and_b = set(a).intersection(b)
every_key = set(a).union(b)
return dict((k, merge(a[k], b[k]) if k in a_and_b else
deepcopy(a[k] if k in a else b[k])) for k in every_key)
return deepcopy(b)
Hmm.. as long as you're not arbitrarily-nested, you don't need recursion.
from itertools import chain
{k:(v if not isinstance(v,dict) else dict(chain(a[k].items(), v.items()))) for k,v in b.items()}
Out[10]: {0: {0: 'a', 1: 'b'}, 1: [3, 4, 5]}
(I'm using python 3 here, feel free to replace .items with .iteritems in python 2)
Since this is a bit verbose, there's always the sneaky way to merge two dicts:
{k:(v if not isinstance(v,dict) else dict(a[k], **v)) for k,v in b.items()}
Out[11]: {0: {0: 'a', 1: 'b'}, 1: [3, 4, 5]}
You may or may not want to use this syntax - though it is compact, it kind of abuses cPython implementation details.
Needed something similar and implemented a more straightforward recursive solution. In-place updates dict 'd'.
from Collections import MutableMapping
def merge(d, v):
"""
Merge two dictionaries.
Merge dict-like `v` into dict-like `d`. In case keys between them are the same, merge
their sub-dictionaries where possible. Otherwise, values in `v` overwrite `d`.
"""
for key in v:
if key in d and isinstance(d[key], MutableMapping) and isinstance(v[key], MutableMapping):
d[key] = merge(d[key], v[key])
else:
d[key] = v[key]
return d
Example 1:
a = {0: {0: "a"},
1: [0, 1, 2]}
b = {0: {1: "b"},
1: [3, 4, 5]}
>>> merge(a, b)
{0: {0: 'a', 1: 'b'}, 1: [3, 4, 5]}
Example 2:
a = {0: {0: 'a'},
1: [0, 1, 2],
2: [9, 9],
3: {'a': {1: 1, 2: 2}, 'b': [0, 1]}}
b = {0: {1: 'b'},
1: [3, 4, 5],
2: {22: 22, 33: 33},
3: {'a': {2: 22, 3: 33}, 'b': [99, 88]}}
>>> merge(a, b)
{0: {0: 'a', 1: 'b'},
1: [3, 4, 5],
2: {22: 22, 33: 33},
3: {'a': {1: 1, 2: 22, 3: 33}, 'b': [99, 88]}}

Categories

Resources