Python 将字符串列表转换为字典的字典

Python 将字符串列表转换为字典的字典,python,python-3.x,Python,Python 3.x,初始输入:- elements = ['description:', '- Hello, Welcome', '- Welcome back', 'type:', '- new', '- existing', 'updated_at:', '- 2017-12-20 09:06:20.599415000 Z',

初始输入:-

elements = ['description:',
            '- Hello, Welcome',
            '- Welcome back',
            'type:',
            '- new',
            '- existing',
            'updated_at:',
            '- 2017-12-20 09:06:20.599415000 Z',
            '- 2017-12-20 09:08:50.398076080 Z'
]
对于上下文,我想将上面的
列表
转换为
dict的
dict
。我还在学习Python,所以我的解释可能不太好

如果字符串中有冒号,则它将用作键。请参考以下文本作为理想输出

理想输出:-

{
    'description': {
        'before': 'Hello, Welcome', 
        'after': 'Welcome back'
    }, 
    'type': {
        'before': 'new', 
        'after': 'existing'
    }, 
    'updated_at': {
        'before': '2017-12-20 09:06:20.599415000 Z', 
        'after': '2017-12-20 09:08:50.398076080 Z'
    }
}
这就是我目前拥有的。但是,它只适用于1号线。剩下的不会产生我想要的。目前,这只处理一个元素。我希望它能够处理整个列以及

elements = df['details'][3].split('\n')[1:]
clean_elements = []
for element in elements:
    if ':' not in element:
        clean_elements[-1] = clean_elements[-1] + element
    else:
        clean_elements.append(element)
clean_elements

data = {}

for element in clean_elements:
    element = element.split(': ')
    data[element[0]] = element[1]

假设您的初始输入实际上是一个列表,并且您总是有一个语法,其中有一个键,然后是旧值,然后是新值(值包含破折号和空格,键包含冒号),那么您可以像这样循环遍历每3个元素:

initial_input = ['a:','- X', '- Y', 'b:', '- C', '- D', 'c:', '- qweqwe', '- asdasd']
result = {}
for i in range(0, len(initial_input), 3):
    key_name = initial_input[i][:-1]
    before_value = initial_input[i+1][2:]
    after_value = initial_input[i+2][2:]
    result[key_name] = {'before': before_value, 'after': after_value}

print result
# {'a': {'after': 'Y', 'before': 'X'}, 'c': {'after': 'asdasd', 'before': 'qweqwe'}, 'b': {'after': 'D', 'before': 'C'}}

如果初始输入是一个字符串,您需要事先使用
json
模块将其解析为一个列表。

假设您的初始输入实际上是一个列表,并且您总是有一个语法,其中有一个键,然后是旧值,然后是新值(值包含破折号和空格,键包含冒号)然后你可以像这样循环3个元素:

initial_input = ['a:','- X', '- Y', 'b:', '- C', '- D', 'c:', '- qweqwe', '- asdasd']
result = {}
for i in range(0, len(initial_input), 3):
    key_name = initial_input[i][:-1]
    before_value = initial_input[i+1][2:]
    after_value = initial_input[i+2][2:]
    result[key_name] = {'before': before_value, 'after': after_value}

print result
# {'a': {'after': 'Y', 'before': 'X'}, 'c': {'after': 'asdasd', 'before': 'qweqwe'}, 'b': {'after': 'D', 'before': 'C'}}

如果初始输入是字符串,则需要事先使用
json
模块将其解析为列表。

您可以使用集合模块中的
deque
之前和
之后“旋转”
。这使得以后添加更多内容变得更容易,而且您也不会硬编码太多

from collections import deque
elements = ['description:',
            '- Hello, Welcome',
            '- Welcome back',
            'type:',
            '- new',
            '- existing',
            'updated_at:',
            '- 2017-12-20 09:06:20.599415000 Z',
            '- 2017-12-20 09:08:50.398076080 Z'
]
my_dict = dict()
# This assumes the first element will always be a key
current_key = None
inner_keys = deque(['before', 'after'])
for element in elements:
    if element.endswith(':'):
        current_key = element.rstrip(':')
        my_dict[current_key] = dict()
    else:
        my_dict[current_key][inner_keys[0]] = element.lstrip('- ')
        inner_keys.rotate()
print(my_dict)
一个
deque
基本上是一个可以旋转元素的集合。
因此,当它包含元素时,调用
rotate()
将其顺序更改为
['before','before']
,反之亦然。

您可以使用集合模块中的
deque
之前和
之后“旋转”
。这使得以后添加更多内容变得更容易,而且您也不会硬编码太多

from collections import deque
elements = ['description:',
            '- Hello, Welcome',
            '- Welcome back',
            'type:',
            '- new',
            '- existing',
            'updated_at:',
            '- 2017-12-20 09:06:20.599415000 Z',
            '- 2017-12-20 09:08:50.398076080 Z'
]
my_dict = dict()
# This assumes the first element will always be a key
current_key = None
inner_keys = deque(['before', 'after'])
for element in elements:
    if element.endswith(':'):
        current_key = element.rstrip(':')
        my_dict[current_key] = dict()
    else:
        my_dict[current_key][inner_keys[0]] = element.lstrip('- ')
        inner_keys.rotate()
print(my_dict)
一个
deque
基本上是一个可以旋转元素的集合。
因此,当它包含元素时,调用
rotate()
['before','after']
将它们的顺序更改为
['after','before']
,反之亦然。

这里有一种方法可以将初始输入转换为所需的输出。我不会对数据帧的内容进行打结,因此我在这里假设
元素
包含初始输入列表,如您文章中的屏幕截图所示

elements = ['description:', '- Hello, Welcome', '- Welcome back',
            'type:', '- new', '- existing',
            'updated_at:', '- 2017-12 09:06:20.599415999 Z', '- 2017-12 09:08:50.398076080 Z']

output = {}
element_iter = iter(elements)
for e in element_iter:
    if e.endswith(':'):
        before = next(element_iter).lstrip('- ')
        after = next(element_iter).lstrip('- ')
        output[e.rstrip(':')] = {'before': before, 'after': after}

print(output)

以下是将初始输入转换为所需输出的一种方法。我不会对数据帧的内容进行打结,因此我在这里假设
元素
包含初始输入列表,如您文章中的屏幕截图所示

elements = ['description:', '- Hello, Welcome', '- Welcome back',
            'type:', '- new', '- existing',
            'updated_at:', '- 2017-12 09:06:20.599415999 Z', '- 2017-12 09:08:50.398076080 Z']

output = {}
element_iter = iter(elements)
for e in element_iter:
    if e.endswith(':'):
        before = next(element_iter).lstrip('- ')
        after = next(element_iter).lstrip('- ')
        output[e.rstrip(':')] = {'before': before, 'after': after}

print(output)

另一种可能的解决方案是:

[外]


另一种可能的解决方案是:

[外]


所以这里的主要思想是循环
元素

当您找到以
结尾的字符串时,您就知道它应该是字典的键

单词之后,循环中的下两项将成为词典的
部分

从集合导入defaultdict
当前_键=无
out=defaultdict(列表)
对于元素中的元素:
#in元素结尾为:它是一个新键
如果elem.strip().endswith(“:”):
当前_key=elem.strip(“:”)
持续
断言当前_键不是None
out[当前_键]。追加(元素[2:])
我们现在有以下格式的数据:

{
    'description': [
        'Hello, Welcome', 
        'Welcome back'
    ], 
    'type': [
        'new', 
        'existing'
   ], 
    'updated_at': [
        '2017-12-20 09:06:20.599415000 Z', 
        '2017-12-20 09:08:50.398076080 Z'
    ]
}
因此,为了将其映射为您想要的字典格式,我们只需迭代项目并将其转换:

for key, value in out.items(): 
    out[key] = dict(zip(['before', 'after'], value))

所以这里的主要思想是循环
元素

当您找到以
结尾的字符串时,您就知道它应该是字典的键

单词之后,循环中的下两项将成为词典的
部分

从集合导入defaultdict
当前_键=无
out=defaultdict(列表)
对于元素中的元素:
#in元素结尾为:它是一个新键
如果elem.strip().endswith(“:”):
当前_key=elem.strip(“:”)
持续
断言当前_键不是None
out[当前_键]。追加(元素[2:])
我们现在有以下格式的数据:

{
    'description': [
        'Hello, Welcome', 
        'Welcome back'
    ], 
    'type': [
        'new', 
        'existing'
   ], 
    'updated_at': [
        '2017-12-20 09:06:20.599415000 Z', 
        '2017-12-20 09:08:50.398076080 Z'
    ]
}
因此,为了将其映射为您想要的字典格式,我们只需迭代项目并将其转换:

for key, value in out.items(): 
    out[key] = dict(zip(['before', 'after'], value))

您还可以使用
itertools.groupby
。这使得每个主键更容易处理不同数量的子键:

from itertools import groupby as gb
elements = ['description:', '- Hello, Welcome', '- Welcome back', 'type:', '- new', '- existing', 'updated_at:', '- 2017-12-20 09:06:20.599415000 Z', '- 2017-12-20 09:08:50.398076080 Z']
r = [list(b) for _, b in gb(elements, key=lambda x:x.startswith('- '))]
d = {r[i][0][:-1]:dict(zip(['before', 'after'], [k[2:] for k in r[i+1]])) for i in range(0, len(r), 2)}
输出:

{
    "description": {
       "before": "Hello, Welcome",
       "after": "Welcome back"
    },
    "type": {
       "before": "new",
       "after": "existing"
    },
    "updated_at": {
       "before": "2017-12-20 09:06:20.599415000 Z",
       "after": "2017-12-20 09:08:50.398076080 Z"
    }
}

您还可以使用
itertools.groupby
。这使得每个主键更容易处理不同数量的子键:

from itertools import groupby as gb
elements = ['description:', '- Hello, Welcome', '- Welcome back', 'type:', '- new', '- existing', 'updated_at:', '- 2017-12-20 09:06:20.599415000 Z', '- 2017-12-20 09:08:50.398076080 Z']
r = [list(b) for _, b in gb(elements, key=lambda x:x.startswith('- '))]
d = {r[i][0][:-1]:dict(zip(['before', 'after'], [k[2:] for k in r[i+1]])) for i in range(0, len(r), 2)}
输出:

{
    "description": {
       "before": "Hello, Welcome",
       "after": "Welcome back"
    },
    "type": {
       "before": "new",
       "after": "existing"
    },
    "updated_at": {
       "before": "2017-12-20 09:06:20.599415000 Z",
       "after": "2017-12-20 09:08:50.398076080 Z"
    }
}

请将您的输入添加为文本而不是图像,您也标记了pandas,但似乎没有要求或使用它,您能澄清一下吗?在“
之前的键
”和“
之后的键
”来自哪里?@Manakin输入来自df中一行中的一列。@Axe319如果我没有提到这一点,很抱歉,如果你看输入的模式,在键后的两行中总是有两个破折号,所以在这种情况下,“before”和“after”不在这里,但我想硬编码它。请将输入添加为文本而不是图像,同时你标记了熊猫,但似乎没有要求或使用它,你能澄清一下吗?在“
之前”和“
之后”的键是从哪里来的吗?@Manakin输入来自df中一行中的一列。@Axe319如果我没有提到这一点,很抱歉,如果你看一下输入的模式,在键后的两行中总是分别有两条虚线,所以在本例中,“before”和“after”不在这里,但我想硬编码