首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Python中将短划线分隔的字符串数据转换为嵌套字典/列表

在Python中将短划线分隔的字符串数据转换为嵌套字典/列表
EN

Stack Overflow用户
提问于 2019-01-03 11:25:12
回答 3查看 174关注 0票数 2

我有一个字符串列表,列表中的每个元素都是指定格式的a-b-c,其中每个a,b,c都是整数,例如,包含大约8000个长度为n-m-k的元素。

代码语言:javascript
复制
myList = ['1-1-1', '1-1-2', '1-2-1', '1-2-2', '1-3-1', ...., n-m-k]

我正在尝试找到一种简单而有效的方法来将其转换为

代码语言:javascript
复制
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']}
}

因为我需要运行基于这些元素的操作,比如一个就地链表。

实现这一目标的最简单方法是什么?

提前谢谢你,

EN

回答 3

Stack Overflow用户

发布于 2019-01-03 11:51:02

如果可以接受整数的元组,则可以使用:

代码语言:javascript
复制
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)

但是如果你真的需要字符串,你可以简单地通过以下方式连接这些键:

代码语言:javascript
复制
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']}}
票数 1
EN

Stack Overflow用户

发布于 2019-01-03 11:59:33

IIUC,你想要的输出实际上是这样的:

代码语言:javascript
复制
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']}
}`

下面是使用itertools.groupby的一种方法

代码语言:javascript
复制
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']}}

通过一些工作,这可以推广到适用于任意数量的破折号。

票数 1
EN

Stack Overflow用户

发布于 2019-01-03 12:08:14

您可以使用列表理解:

代码语言:javascript
复制
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}

输出:

代码语言:javascript
复制
{'1': {'1-2': ['1-2-1', '1-2-2'], '1-1': ['1-1-1', '1-1-2'], '1-3': ['1-3-1']}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54015933

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档