如何在Python中将字符串列表转换为字典列表?

7

I have a string with format:

["('colA':'datA1', 'colB':'datB1', 'colC':'datC1')",
 "('colA':'datA2', 'colB':'datB2', 'colC':'datC2')",
 ..........
 "('colA':'datAn', 'colB':'datBn', 'colC':'datCn')]

我需要获取一个字典:

[{'colA': 'datA1', 'colB': 'datB1', 'colC': 'datC1'},
 {'colA': 'datA2', 'colB': 'datB2', 'colC': 'datC2'},
 ..........
 {'colA': 'datAn', 'colB': 'datBn', 'colC': 'datCn'}]

如果可能的话,我需要使用Python自带函数来实现,或者至少不使用循环,但我不知道这是否可行。

2
“jack”来自哪里?原始数据中没有这个。Sape也不是。数字4098和4130来自哪里?是从计算中得出的吗? - Anthon
抱歉,剪贴板出现错误。感谢您指出。我会进行编辑。 - Juan Antonio Clavero Garcia
呵呵,如果字符串中没有括号(和)的话,你就可以在每个字符串上运行eval()。 - David Bern
5个回答

11

将括号替换为花括号,并使用ast.literal_eval

import ast
l = ["('colA':'datA1', 'colB':'datB1', 'colC':'datC1')",
 "('colA':'datA2', 'colB':'datB2', 'colC':'datC2')",
 "('colA':'datAn', 'colB':'datBn', 'colC':'datCn')"]
result = [ast.literal_eval('{%s}' % item[1:-1]) for item in l]

结果:

>>> import pprint
>>> pprint.pprint(result)
[{'colA': 'datA1', 'colB': 'datB1', 'colC': 'datC1'},
 {'colA': 'datA2', 'colB': 'datB2', 'colC': 'datC2'},
 {'colA': 'datAn', 'colB': 'datBn', 'colC': 'datCn'}]

3
这是正确的回答 - 像其他人建议的那样,仅使用纯粹的“eval”可能是危险的。请参见http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html。 - n1c9

2

避免使用不安全的eval函数,应该依赖于正确的字典结构(以json表示)。使用以下方法和re.subjson.loads函数:

import json, re

d = ["('colA':'datA1', 'colB':'datB1', 'colC':'datC1')",
 "('colA':'datA2', 'colB':'datB2', 'colC':'datC2')",
 "('colA':'datAn', 'colB':'datBn', 'colC':'datCn')"]

try:
    l = [json.loads('{' + re.sub(r'\'', '"', s).strip('()') + '}') for s in d]
    print(l)
except json.decoder.JSONDecodeError as err:
    print('JSONDecodeError: ', err)

输出结果:
[{'colC': 'datC1', 'colA': 'datA1', 'colB': 'datB1'}, {'colC': 'datC2', 'colA': 'datA2', 'colB': 'datB2'}, {'colC': 'datCn', 'colA': 'datAn', 'colB': 'datBn'}]

那个裸的 except: 该捕获什么样的异常? - TigerhawkT3
@TigerhawkT3,在一些简单的情况下可以使用裸露的方式,但现在我已经添加了特定的异常类型,请查看我的更新。在更严格(真实)的情况下,当然我们可以使用raise Exception('...') - RomanPerekhrest

2

正如@nexus66所建议的那样,这是该答案的更简化版本:

l = ["('colA':'datA1', 'colB':'datB1', 'colC':'datC1')",
 "('colA':'datA2', 'colB':'datB2', 'colC':'datC2')",
 "('colA':'datAn', 'colB':'datBn', 'colC':'datCn')"]
result = [dict(
               item.replace("'", '').split(':')
               for item in s[1:-1].split(', ')
               )
          for s in l]

谢谢你的回答! - Chiheb Nexus
谢谢您给我的两个答案。我更喜欢这个,因为它不使用额外的模块。 - Juan Antonio Clavero Garcia

1

我对你的问题的解决方案不需要导入任何模块:

my_input = ["('colA':'datA1', 'colB':'datB1', 'colC':'datC1')",
 "('colA':'datA2', 'colB':'datB2', 'colC':'datC2')",
 "('colA':'datAn', 'colB':'datBn', 'colC':'datCn')"]

global_list =[]
for i in my_input:
    intern_dict = {}
    for j in i.replace("(", "").replace(")", "").split(","):
        c = j.split(":")
        intern_dict["".join(c[0].replace("'", "").strip())] = "".join(c[1].replace("'","").strip())     
    global_list.append(intern_dict)

print("Type of global_list: {0}\n".format(type(global_list)))
print(global_list)
print("\nType of elements inside global_list\n")
for i in global_list:
    print("{0}\tType: {1}".format(i, type(i)))

输出:

Type of global_list: <class 'list'>

[{'colA': 'datA1', 'colC': 'datC1', 'colB': 'datB1'}, {'colA': 'datA2', 'colC': 'datC2', 'colB': 'datB2'}, {'colA': 'datAn', 'colC': 'datCn', 'colB': 'datBn'}]

Type of elements inside global_list

{'colA': 'datA1', 'colC': 'datC1', 'colB': 'datB1'} Type: <class 'dict'>
{'colA': 'datA2', 'colC': 'datC2', 'colB': 'datB2'} Type: <class 'dict'>
{'colA': 'datAn', 'colC': 'datCn', 'colB': 'datBn'} Type: <class 'dict'>

1
这个算法有一些明显的怪异之处,比如不必要的生成器表达式 k for k in... - TigerhawkT3
1
''.join(k for k in iterable) 的作用与 ''.join(iterable) 相同。 - TigerhawkT3
是的!你说得对。我修改了我的答案。谢谢你指出了这些问题。 - Chiheb Nexus
1
整个代码可能只需要这一行:result = [dict(item.replace("'", '').split(':') for item in s[1:-1].split(', ')) for s in my_input] - TigerhawkT3
太棒了!你应该发布你的解决方案。它更符合Python风格! - Chiheb Nexus
让我们在聊天中继续这个讨论。点击此处进入聊天室 - Chiheb Nexus

-3

使用 JSON

import json

lst = "yourstringhere"

dict = json.load(lst)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接