J'ai une liste de chaînes où chaque élément de la liste est au format spécifié abc
où chaque a, b, c sont des entiers, par exemple, contient environ 8000 éléments dont la longueur de nmk varie.
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']} }
J'essaie de trouver un moyen simple et efficace de convertir cela en
myList = ['1-1-1', '1-1-2', '1-2-1', '1-2-2', '1-3-1', ...., n-m-k]
Comme j'ai besoin d'exécuter des opérations basées sur ces éléments, comme une liste liée sur place.
Quelle est la manière la plus simple d'y parvenir?
Merci d'avance,
3 Réponses :
Si peut accepter des tuples d'entiers, vous pouvez utiliser:
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']}}
Mais si vous avez vraiment besoin de chaînes, vous pouvez simplement joindre les clés via:
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)
IIUC, la sortie souhaitée est en fait quelque chose comme:
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']}}
Voici une façon d'utiliser itertools.groupby
:
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']} }`
Une mise en garde ici est que cela suppose que la liste d'origine est triée.
Vous pouvez utiliser une compréhension de liste:
{'1': {'1-2': ['1-2-1', '1-2-2'], '1-1': ['1-1-1', '1-1-2'], '1-3': ['1-3-1']}
Sortie:
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}
Il n'y a pas de moyen simple. Vous devez diviser chaque élément de votre liste et parcourir n, m et k et l'enregistrer dans votre dict. Votre logique n'est pas non plus particulièrement claire. Pouvez-vous donner un exemple de ce que
1-1-1
produira exactement? Il en va de même pour1-2-1
et1-1-2