Skip to main content
 首页 » 编程设计

python之解析这些数据的最佳 Pythonic 方式是什么

2025年05月04日16dudu

我是 Python 的新手,正在尝试找到最符合 Pythonic 的方法来解析来自 LDAP 查询的响应。到目前为止,我所做的一切都有效,但如果可能的话,我想让它更整洁。我的响应数据是这样的:

"[[('CN=LName\\, FName,OU=MinorUserGroup,OU=MajorUserGroup,DC=my,DC=company,DC=com', {'department': ['theDepartment'], 'mail': ['theEmail@mycompany.com']})]]" 

在这些数据中,我真的只对 {} 中的字段感兴趣,这样我就可以将其放入字典中...

"department:theDepartment,mail:theEmail@mycompany.com" 

我现在正在做的事情感觉(看起来)真的很蛮力,但确实有效。我添加了额外的评论并根据每个步骤正在做的事情输出结果,以尝试详细说明这一困惑局面。

#Original String 
#"[[('CN=LName\\, FName,OU=MinorUserGroup,OU=MajorUserGroup,DC=my,DC=company,DC=com', {'department': ['theDepartment'], 'mail': ['theEmail@mycompany.com']})]]" 
 
#split at open {, take the latter half 
myDetails = str(result_set[0]).split('{')  
#myDetails[1] = ["'department': ['theDepartment'], 'mail': ['theEmail@mycompany.com']})]]"] 
 
#split at close }, take the former half 
myDetails = str(myDetails[1]).split('}')  
#myDetails[0] = ["'department': ['theDepartment'], 'mail': ['theEmail@mycompany.com']"] 
 
#split at comma to separate the two response fields 
myDetails = str(myDetails[0]).split(',')  
#myDetails = ["'department': ['theDepartment']","'mail': ['theEmail@mycompany.com']"] 
 
#clean up the first response field 
myDetails[0] = str(myDetails[0]).translate(None, "'").translate(None," [").translate(None,"]")  
#myDetails[0] = ["department:theDepartment"] 
 
#clean up the second response field 
myDetails[1] = str(myDetails[1]).translate(None," '").translate(None, "'").translate(None,"[").translate(None,"]") 
#myDetails[1] = ["mail:theEmail@mycompany.com"] 

虽然我非常喜欢“如果它没有坏,就不要修理它”,但我更喜欢效率。

编辑 根据@Mario 接受的答案,这最终对我有用

myUser = ast.literal_eval(str(result_set[0]))[0][1]  
myUserDict = { k: v[0] for k, v in myUser.iteritems() } 

请您参考如下方法:

相信您的输入并依靠其严格的规律性,这将解析您的示例数据并生成您期望的结果:

import ast 
 
ldapData = "[[('CN=LName\\, FName,OU=MinorUserGroup,OU=MajorUserGroup,DC=my,DC=company,DC=com', {'department': ['theDepartment'], 'mail': ['theEmail@mycompany.com']})]]" 
 
# Using the ast module's function is much safer than using eval. (See below!) 
obj = ast.literal_eval(ldapData)[0][0] 
rawDict = obj[1] 
data = { k: v[0] for k, v in rawDict.iteritems() } 
 
# The dictionary. 
print data 

使用大括号的行称为字典理解。


编辑:该线程的另一位用户建议使用 ast.literal_eval 函数。在研究了这个之后,我必须同意。 eval 函数将执行任何字符串。如果输入是这样的,你就会遇到大问题:

eval("__import__('os').system('rm -R *')")  

另一方面,如果使用 ast 函数解析同一个字符串,则会出现异常:

>>> import ast 
>>> ast.literal_eval("__import__('os').system('rm -R *')") 
Traceback (most recent call last): 
  File "<stdin>", line 1, in <module> 
  File "/usr/lib64/python2.7/ast.py", line 80, in literal_eval 
    return _convert(node_or_string) 
  File "/usr/lib64/python2.7/ast.py", line 79, in _convert 
    raise ValueError('malformed string') 
ValueError: malformed string 
>>>  

可以在这里找到进一步的讨论:

http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html

模块的文档在这里:

https://docs.python.org/2/library/ast.html