初始输入:-
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'
]
对于上下文,我想将上面的 list
转换为 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]
答案 0 :(得分:2)
这是将初始输入转换为所需输出的一种方法。我不会打结您数据框的内容,因此我在这里假设 elements
包含初始输入列表,如您帖子中的屏幕截图所示。
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)
答案 1 :(得分: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
模块将其解析为列表。
答案 2 :(得分:1)
另一个使用 dict comprehension 的潜在解决方案:
d = {elements[i].strip(':'):{'before': elements[i+1].strip('- '),
'after': elements[i+2].strip('- ')}
for i in range(0, len(elements), 3)}
[出]
{'description': {'before': 'Hello, Welcome', 'after': 'Welcome back'},
'type': {'before': 'new', 'after': 'existing'},
'updated_at': {'before': '2017-12 09:06:20.599415999 Z',
'after': '2017-12 09:08:50.398076080 Z'}}
答案 3 :(得分:0)
您可以使用集合模块中的 deque
来“旋转”before
和 after
。这样可以更轻松地在以后添加更多内容,而且您无需进行过多的硬编码。
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']
,反之亦然。
答案 4 :(得分:0)
所以这里的主要思想是遍历 elements
。
当您找到以 :
结尾的字符串时,您就知道它应该是您字典的键。
在单词之后,循环中的下两个项目将成为字典的 before
和 after
部分。
from collections import defaultdict
current_key = None
out = defaultdict(list)
for elem in elements:
# in element ends with : it is a new key
if elem.strip().endswith(':'):
current_key = elem.strip(':')
continue
assert current_key is not None
out[current_key].append(elem[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))
答案 5 :(得分:0)
您也可以使用 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"
}
}