Reputation: 93
I have list of strings where each element in the list is in the specified format a-b-c
where each a,b,c are integers, e.g, contains about 8000 elements lengths of n-m-k vary.
myList = ['1-1-1', '1-1-2', '1-2-1', '1-2-2', '1-3-1', ...., n-m-k]
I am trying to find a simple and efficient way to convert this into
myDict = {
'1': {
'1-1': ['1-1-1','1-1-2','1-1-3','1-1-4'],
'1-2': ['1-2-1','1-2-2'],
'1-3': ['1-3-1']
},
....,
'n': {.....,'n-m':[....,'n-m-k']}
}
As I need to run operations based on these elements, like an in-place linked-list.
What is the easiest way to achieve this?
Thanks in Advance,
Upvotes: 2
Views: 321
Reputation: 71461
You can use a list comprehension:
myList = ['1-1-1', '1-1-2', '1-2-1', '1-2-2', '1-3-1']
_split = list(map(lambda x:x.split('-'), myList))
s, s2 = {a for a, *_ in _split}, {f'{a}-{b}' for a, b, _ in _split}
new_data = {i:{c:[h for h in myList if h.startswith(c)] for c in s2 if c[0] == i} for i in s}
Output:
{'1': {'1-2': ['1-2-1', '1-2-2'], '1-1': ['1-1-1', '1-1-2'], '1-3': ['1-3-1']}
Upvotes: 1
Reputation: 43524
IIUC, your desired output is actually something like:
myDict = {
'1': {
'1-1': ['1-1-1','1-1-2','1-1-3','1-1-4'],
'1-2': ['1-2-1','1-2-2'],
'1-3': ['1-3-1']
},
....,
'n': {.....,'n-m':[....,'n-m-k']}
}`
Here's one way using itertools.groupby
:
from itertools import groupby
myList = [
'1-1-1','1-1-2','1-2-1','1-2-2','1-3-1', '2-1-1', '2-2-2', '2-2-3', '4-5-6'
]
# a helper function
def mySplit(s, max_split):
return {
v: list(g)
for v, g in groupby(
s,
lambda x: "-".join(x.split("-", max_split)[:max_split])
)
}
myDict = {v: mySplit(g, 2) for v, g in groupby(myList, lambda x: x.split("-", 1)[0])}
print(myDict)
#{'1': {'1-1': ['1-1-1', '1-1-2'], '1-2': ['1-2-1', '1-2-2'], '1-3': ['1-3-1']},
# '2': {'2-1': ['2-1-1'], '2-2': ['2-2-2', '2-2-3']},
# '4': {'4-5': ['4-5-6']}}
With some work, this can be generalized to work for an arbitrary number of dashes.
Upvotes: 1
Reputation: 36691
If can accept tuples of integers, you can use:
x = ['1-1-1','1-1-2', '1-2-1', '1-2-2', '1-3-1']
y3 = [tuple(map(int,a.split('-'))) for a in x]
y2 = set(a[:2] for a in y3)
y1 = set(a[0] for a in y2)
d = {}
for k1 in y1:
d1 = {}
d[k1] = d1
for k2 in (z for z in y2 if z[0]==k1):
a2 = []
d1[k2] = a2
for a in (z for z in y3 if z[0]==k1 and z[1]==k2[1]):
a2.append(a)
But if you really need strings, you can simply join the keys via:
x = ['1-1-1','1-1-2', '1-2-1', '1-2-2', '1-3-1']
y3 = [tuple(a.split('-')) for a in x]
y2 = set(a[:2] for a in y3)
y1 = set(a[0] for a in y2)
d = {}
for k1 in y1:
d1 = {}
d[k1] = d1
for k2 in (z for z in y2 if z[0]==k1):
a2 = []
d1['-'.join(k2)] = a2
for a in (z for z in y3 if z[0]==k1 and z[1]==k2[1]):
a2.append('-'.join(a))
d
# returns:
{'1': {'1-1': ['1-1-1', '1-1-2'], '1-2': ['1-2-1', '1-2-2'], '1-3': ['1-3-1']}}
Upvotes: 1