python - 如何将值附加到嵌套字典中的键并避免使用括号
问题描述
我有一个代码,它将下面文件中的这些行格式化为字典:
CommonChar pins Category General
CommonChar pins Contact Mark
CommonChar pins Description This is a
CommonChar nails Category specific
CommonChar nails Contact John
CommonChar pins Description This is a description
最终的字典看起来像这样:
main_dict = {
'pins':
{
'Category': ['General'],
'Contact': ['Mark'],
'Description': ['This', 'is', 'a']
},
'nails':
{
'Category': ['specific'],
'Contact': ['Jon'],
'Description': ['This', 'is', 'a', 'description']
}}
我今天有这个代码来创建上面的字典:
filePath= os.path.join(dirName,eachFile)
fh=open(filePath, "r")
contents=fh.read()
items=re.findall("CommonChar.*$",contents,re.MULTILINE)
for x in items:
parts=x.split()
if parts[1] in mainDict:
if parts[2] in mainDict[parts[1]]:
sys.exit("exit")
else:
mainDict[parts[1]].update({parts[2]:parts[3:]})
else:
mainDict[parts[1]]={}
mainDict[parts[1]].update({parts[2]:parts[3:]})
如果我对代码的输入发生如下变化,那么我需要附加类似键的值:
CommonChar pins Category General
CommonChar pins Contact Mark
CommonChar pins Description This is a
CommonChar pins Description secondLine
CommonChar nails Category specific
CommonChar nails Contact John
CommonChar pins Description This is a description
我需要从上面的行中得到这样的输出:
</br>
也被添加到其中。
main_dict = {
'pins':
{
'Category': ['General'],
'Contact': ['Mark'],
'Description': ['This', 'is', 'a','</br>','secondLine']
},
'nails':
{
'Category': ['specific'],
'Contact': ['Jon'],
'Description': ['This', 'is', 'a', 'description']
}}
为此,我正在替换这一行:
sys.exit("exit")
有了这个:
mainDict[parts[1]][parts[2]].append(parts[3:])
但我得到这样的输出:
main_dict = {
'pins':
{
'Category': ['General'],
'Contact': ['Mark'],
'Description': ['This', 'is', 'a',['secondLine']]
},
'nails':
{
'Category': ['specific'],
'Contact': ['Jon'],
'Description': ['This', 'is', 'a', 'description']
}}
那么如何避免将那些额外的 [ ] 添加到 secondLine 并添加
</br>
在它面前?
解决方案
这个怎么样?我对您的代码进行了一些更改:
- 在一个子句中打开并读取文件
with
,以保证它在完成后关闭。 - 将每个项目拆分为有意义的变量,以便更轻松地跟踪正在发生的事情。
- 使用 Python 风格的命名和标点而不是 Matlab (
main_dict = {}
vs.mainDict={}
)。 - 用于在分配给每个组之前
setdefault
确保main_dict
每个组都有一个空的字典(这通常比使用单独的分支在不存在时创建条目或在存在时更新它时更容易维护。) - 用于
.extend
代替.append
向有效负载列表添加更多项目。
/tmp/data1.txt
CommonChar pins Category General
CommonChar pins Contact Mark
CommonChar pins Description This is a
CommonChar pins Description secondLine
/tmp/data2.txt
CommonChar nails Category specific
CommonChar nails Contact John
CommonChar nails Description This is a description
files
script.py(更新为扫描变量中列出的多个文件)
import re, pprint
files = ['/tmp/data1.txt', '/tmp/data2.txt']
main_dict = {}
for filename in files:
with open(filename, "r") as fh:
contents = fh.read()
items = re.findall("CommonChar.*$", contents, re.MULTILINE)
for x in items:
cc, group, topic, data = x.split(None, 3)
data = data.split()
group_dict = main_dict.setdefault(group, {'fileLocation': [filename]})
if topic in group_dict:
group_dict[topic].extend(['</br>'] + data)
else:
group_dict[topic] = data
pprint.pprint(main_dict)
输出
{'nails': {'Category': ['specific'],
'Contact': ['John'],
'Description': ['This', 'is', 'a', 'description'],
'fileLocation': ['/tmp/data.txt']},
'pins': {'Category': ['General'],
'Contact': ['Mark'],
'Description': ['This', 'is', 'a', '</br>', 'secondLine'],
'fileLocation': ['/tmp/data.txt']}}
顺便说一句,如果您的代码遇到错误,它应该引发异常,而不是sys.exit()
调用raise ValueError("Bad value in file")
.
您在对您的问题的评论中询问上述代码是否等同于您的代码,如下所示:
if parts[1] in mainDict:
if parts[2] in mainDict[parts[1]]:
mainDict[parts[1]][parts[2]].extend(['</br>']+parts[3:])
else:
mainDict[parts[1]].update({parts[2]:parts[3:]})
else:
mainDict[parts[1]]={}
mainDict[parts[1]].update({parts[2]:parts[3:]})
它是,这里是它是如何工作的细分。首先,该行等效于,并且cc, group, topic, data = x.split(None, 3)
等效于。然后下一行相当于. 进行这些替换会得到以下结果:group
parts[1]
topic
parts[2]
data
parts[3:]
if group in mainDict:
if topic in mainDict[group]:
mainDict[group][topic].extend(['</br>'] + data)
else:
mainDict[group].update({topic: data]})
else:
mainDict[group]={}
mainDict[group].update({topic: data]})
接下来,我们注意到上面的代码等价于:
# next line sets groupDict=mainDict[group], creating it if needed
groupDict = mainDict.setdefault(group, {})
if topic in groupDict:
groupDict[topic].extend(['</br>'] + data)
else:
groupDict.update({topic: data]})
最后,我们注意到可以在第一次创建 groupDict 时存储文件名,这groupDict.update({topic: data]})
相当于groupDict[topic] = data
. 通过这些更改,我们得到:
groupDict = mainDict.setdefault(group, {'fileLocation': [filename]})
if topic in groupDict:
groupDict[topic].extend(['</br>'] + data)
else:
groupDict[topic] = data
除了拼写之外,这与我的解决方案的最后五行相同:
group_dict = main_dict.setdefault(group, {'fileLocation': [filename]})
if topic in group_dict:
group_dict[topic].extend(['</br>'] + data)
else:
group_dict[topic] = data
推荐阅读
- php - pdo驱动在linux中没有价值
- deployment - 构建 Netbeans / Ant java 项目时跨本机库(非 jar)复制到 dmg
- react-native-android - 线程“主”java.util.zip.ZipException 中的异常:打开 zip 文件时出错
- javascript - Javascript:根据两个标准拆分字符串?
- reactjs - 文件夹上传 Electron
- sql - 一种方式 SQL server dbs之间的数据传输技术,除了跨国复制
- arrays - $_POST PHP 数组
- virtualbox - 如何从崩溃的 Virtualbox VM 中恢复丢失的数据?
- c# - 如何在给定字符串中查找数字的索引
- node.js - 如何使用我的 nodejs-express 应用程序处理被重定向为 https 的 http 请求?