How to convert this list into dictionary in Python? - python

I have a list like this:
paths = [['test_data', 'new_directory', 'ok.txt'], ['test_data', 'reads_1.fq'], ['test_data', 'test_ref.fa']]
I want to convert this into dictionary like this:
{'test_data': ['ok.txt', 'reads_1.fq'], 'test_data/new_directory', ['ok.txt']}
The list is dynamic. The purpose of this is to create a simple tree structure. I want to do this using itertools like this:
from itertools import izip
i = iter(a)
b = dict(izip(i, i))
Is something like this possible? Thanks

can try this also,
list1=['a','b','c','d']
list2=[1,2,3,4]
we want to zip these two lists and create a dictionary dict_list
dict_list = zip(list1, list2)
dict(dict_list)
this will give:
dict_list = {'a':1, 'b':2, 'c':3, 'd':4 }

Yes it is possible, use collections.defaultdict:
>>> from collections import defaultdict
>>> dic = defaultdict(list)
>>> lis = [['test_data', 'new_directory', 'ok.txt'], ['test_data', 'reads_1.fq'],
for item in lis:
key = "/".join(item[:-1])
dic[key].append(item[-1])
...
>>> dic
defaultdict(<type 'list'>,
{'test_data': ['reads_1.fq', 'test_ref.fa'],
'test_data/new_directory': ['ok.txt']})
using simple dict:
>>> dic = {}
>>> for item in lis:
key = "/".join(item[:-1])
dic.setdefault(key, []).append(item[-1])
...
>>> dic
{'test_data': ['reads_1.fq', 'test_ref.fa'],
'test_data/new_directory': ['ok.txt']}

Related

Is it possible to add another level of keys iteratively to a dictionary to generate a nested dictionary?

So my idea is to kind of generate a dictionary in such a way:
my_dict = {}
for x in range(len(something)):
for y in range(len(something_else)):
my_dict[x] = {}
my_dict[x][y] = {key: value}
However, when I try doing it like this, I always end up getting the error message:
KeyError: 0 or KeyError: '0' if I use strings instead of integers.
Any idea what I might be doing wrong?
Doing what your are doing you "erase" my_dict[x] on each y loop.
Try:
my_dict = {}
for x in range(len(something)):
for y in range(len(something_else)):
d = my_dict.setdefault(x, {})
d[y] = {key: value}
Or:
my_dict = {}
for x in range(len(something)):
my_dict[x] = {}
for y in range(len(something_else)):
my_dict[x][y] = {}
for z in range(len(other)):
my_dict[x][y][z] = {key: value}
You can create an arbitrarily nested dictionary with ease using collections.defaultdict:
from collections import defaultdict
make_dict = lambda: defaultdict(make_dict)
my_dict = make_dict()
my_dict[1][2][3] = 4 # wrap this inside a nested loop as deep as you like
my_dict
defaultdict(<function __main__.<lambda>()>,
{1: defaultdict(<function __main__.<lambda>()>,
{2: defaultdict(<function __main__.<lambda>()>,
{3: 4})})})

Usage of setdefault instead of defaultdict

I need to create a structure like this :
D = {i:{j:{k:0,l:1,m:2}},a:{b:{c:0,d:4}}}
So this can be done using defaultdict:
D = defaultdict(defaultdict(Counter))
How do i use setdefault here?
EDIT :
Is it possible to combine setdefault and defaultdict ?
To build a multi-level dictionary with setdefault() you'd need to repeatedly access the keys like this:
>>> from collections import Counter
>>> d = {}
>>> d.setdefault("i", {}).setdefault("j", Counter())
Counter()
>>> d
{'i': {'j': Counter()}}
To generalize the usage for new keys you could use a function:
def get_counter(d, i, j):
return d.setdefault(i, {}).setdefault(j, Counter())

storing Dictionary as value on another Dictionary in Python

I'm trying to create a dictionary that takes a key and returns another dictionary that takes a different key and returns a value, but I'm having difficulty on implementing this.
I've tried something like this:
FirstDict[key1]=SecondDict
SecondDict[key2]=Final Value
I'd like to be able to call it like SecondDict[key1][key2] but I'm unable to do so.
You can create multi-level nested dictionaries with collections.defaultdict, like this
from collections import defaultdict
def multi_level_dict():
return defaultdict(multi_level_dict)
You can use it like this
my_dict = multi_level_dict()
my_dict[1][2][3] = "cabbage"
my_dict[1][4][5] = "salad"
from pprint import pprint
pprint(my_dict)
# {1: {2: {3: 'cabbage'},
# 4: {5: 'salad'}}}
>>> a = {}
>>> b = {}
>>> a['key1'] = b
>>> b['key2'] = 'final value'
>>> a['key1']
{'key2': 'final value'}
>>> a['key1']['key2']
'final value'
>>>
I tested, it works!
You can create nested dictionaries with NestedDict
>>> from ndicts.ndicts import NestedDict
>>> nd = NestedDict()
>>> nd["a", "a"] = 0
>>> nd["a", "b"] = 1
>>> nd["b"] = 2
>>> nd
NestedDict({'a': {'a': 0, 'b': 1}, 'b': 2})
Once you have a NestedDict, get value using tuples as in a flat dictionary
>>> nd["a", "a"]
0
To install ndicts pip install ndicts

Python: from lists, build dict with key:value ratio not 1:1

Pardon me for not finding a better title.
Say I have two lists:
list1 = ["123", "123", "123", "456"]
list2 = ["0123", "a123", "1234", "null"]
which describe a mapping (see this question). I want to create a dict from those lists, knowing that list1 contains the keys and list2 the values. The dict in this case should be:
dict1 = {"123":("0123", "a123", "1234"), "456":("null",)}
because list1 informs us that "123" is associated to three values.
How could I programmatically generate such a dictionary?
from collections import defaultdict
dd = defaultdict(list)
for key, val in zip(list1, list2):
dd[key].append(val)
defaultdict() is your friend:
>>> from collections import defaultdict
>>> result = defaultdict(tuple)
>>> for key, value in zip(list1, list2):
... result[key] += (value,)
...
This produces tuples; if lists are fine, use Jon Clement's variation of the same technique.
>>> from collections import defaultdict
>>> list1 = ["123", "123", "123", "456"]
>>> list2 = ["0123", "a123", "1234", "null"]
>>> d = defaultdict(list)
>>> for i, key in enumerate(list1):
... d[key].append(list2[i])
...
>>> d
defaultdict(<type 'list'>, {'123': ['0123', 'a123', '1234'], '456': ['null']})
>>>
And a non-defaultdict solution:
from itertools import groupby
from operator import itemgetter
dict( (k, tuple(map(itemgetter(1), v))) for k, v in groupby(sorted(zip(list1,list2)), itemgetter(0)))

Oneline population of dictionary from array in Python

I need to populate dictionary from array. I've done in three lines and i'm trying to do it shortest as it can be. Is there way how to populate it in single line?
a = [['test',154],['test2',256]]
d = dict()
for b in a:
d[b[0]] = b[1]
Just dict :)
>>> a = [['test',154],['test2',256]]
>>> dict(a)
{'test': 154, 'test2': 256}
You just do dict(a) or dict([['test',154],['test2',256]]).
L = [['test',154],['test2',256]]
In Python 3.x:
d = {k:v for k,v in L}
In Python 2.x:
d = dict([(k,v) for k,v in L])

Categories