python-3.x - Python如何在列表中从文件到字典
问题描述
我有如下格式字符串的文件。总是有六个字段,有时用户错误地输入了某些字段,所以我尝试使用正则表达式来匹配该字段。
name : Luke Skywalker
hp. : 0813412345678
address : Jl. Gagak 3 No.5 Bandung Selatan
product : TSirt Starwars
quantity : 1
note : size L
name : Qui-Gon Jinn
hp. : 08156898234567
address : Jl. Tatoon No.142 Bandung Barat
product : pants Chino Krem
quantity : 1
note : size L
name : Obi-Wan Kenobi
hp. : 08877763212312
address : Jl. Pemuda No.66 Bandung Selatan
product : TSirt Starwars
quantity : 1
note : size L
我想用这样的格式在列表中制作字典。
[
{
'name': 'Luke Skywalker',
'mobile': '0813412345678',
'address': 'Jl. Gagak 3 No.5 Bandung Selatan',
'product': 'TSirt Starwars',
'quantity': '1',
'note': 'size L'
},
{
'name': 'Qui-Gon Jinn',
'mobile': '08156898234567',
'address': 'Jl. Tatoon No.142 Bandung Barat',
'product': 'pants Chino Krem',
'quantity': '1',
'note': 'size L'
},
{
'name': 'Obi-Wan Kenobi',
'mobile': '08877763212312',
'address': 'Jl. Pemuda No.66 Bandung Selatan',
'product': 'TSirt Starwars',
'quantity': '1',
'note': 'size L'
}
]
到目前为止,我已成功使用此代码:
# -*- coding: utf-8 -*-
import re
_lst = []
with open("filetoread.txt", "r") as read_file:
_tmp_name = []
_tmp_mobile = []
_tmp_alamat = []
_tmp_produk = []
_tmp_jml = []
_tmp_note = []
for i in read_file:
if i is not "\n":
_splt = i.split(":")
if re.compile(r"nam[a|e]", re.I).match(_splt[0].strip()):
_tmp_name.append({"name":_splt[1].strip()})
if re.compile(r"^hp(\.\s)?|^hand\w|telp(\.\s)?", re.I).match(_splt[0].strip()):
_tmp_mobile.append({"mobile":_splt[1].strip()})
if re.compile(r"alamat|address", re.I).match(_splt[0].strip()):
_tmp_alamat.append({"addredd":_splt[1].strip()})
if re.compile(r"produk|item", re.I).match(_splt[0].strip()):
_tmp_produk.append({"product":_splt[1].strip()})
if re.compile(r"jml(\.\s)?|jumlah|total", re.I).match(_splt[0].strip()):
_tmp_jml.append({"quantity":_splt[1].strip()})
if re.compile(r"note", re.I).match(_splt[0].strip()):
_tmp_note.append({"note":_splt[1].strip()})
_zip = list(zip(_tmp_name, _tmp_mobile, _tmp_alamat, _tmp_produk, _tmp_jml, _tmp_note))
l = []
for z in _zip:
d = {}
for i in z:
d.update(i)
l.append(d)
print(l)
但我不太确定这段代码。有没有更好的方法以更简单和聪明的python方式来做。
谢谢提前。
解决方案
您可以使用 topy 模块(pip3 install topy --user):此模块旨在使用正则表达式规则(https://github.com/intgr/topy)修复拼写错误和其他规则。规则存储在文件中。下面是这样一个规则文件(“rules.txt”)的内容示例:
<Typo word="address" find="alamat|\b([aA])d+res(ab[il][a-z]+|e(?:[ds]|[er]s?)|ing)?\b" replace="address"/>
<Typo word="name" find="nam[a|e]|\b([nN])mae" replace="name"/>
<Typo word="mobile" find="hp(\.|\s)?|^hand\w|telp(\.\s)?" replace="mobile"/>
<Typo word="product" find="produk|item" replace="product"/>
<Typo word="quantity" find="jml(\.\s)?|jumlah|total" replace="quantity"/>
<Typo word="T-shirt" find="[tT][sS]irt" replace="T-shirt"/>
然后,我们可以如下处理*filetoread.txt(假设“rules.txt”存在):
import os
from shutil import copyfile
from topy import topy
filename='filetoread.txt' # file to parse
rules='rules.txt' # file containing regex rules
# Let's make a copy of the original file (not necessary but useful for debug)
# For debuging purpose, we will work on the copy instead of the original file.
newfile=filename.strip('.txt')+'_copy.txt' # filetoread.txt --> filetoread_copy.txt
copyfile(filename, newfile);
topy.main([ '--rules', rules, '--apply', newfile]) # apply the rules and overwrite newfile
# Then we create our array of dict:
d=[]
D = {}
with open(newfile) as f:
for line in f:
line=line.replace('\n','')
if len(line)>0:
(key, val) = line.split(":")
D[key]=val
else:
if D:
d.append(D)
D={}
print(d)
举个例子:
对于以下输入文件 (filetoread.txt):
nama: Luke Skywalker
hp. : 0813412345678
address : Jl. Gagak 3 No.5 Bandung Selatan
product : TSirt Starwars
quantity : 1
note : size L
nmae : Qui-Gon Jinn
hp.: 08156898234567
alamat : Jl. Tatoon No.142 Bandung Barat
product : pants Chino Krem
quantity : 1
note : size L
name : Obi-Wan Kenobi
telp. : 08877763212312
addres : Jl. Pemuda No.66 Bandung Selatan
product : TSirt Starwars
jml. : 1
note : size L
输出是:
[{'name': ' Luke Skywalker',
'mobile ': ' 0813412345678',
'address ': ' Jl. Gagak 3 No.5 Bandung Selatan',
'product ': ' T-shirt Starwars ',
'quantity ': ' 1',
'note ': ' size L'},
{'name ': ' Qui-Gon Jinn',
'mobile': ' 08156898234567',
'address ': ' Jl. Tatoon No.142 Bandung Barat',
'product ': ' pants Chino Krem',
'quantity ': ' 1',
'note ': ' size L'},
{'name ': ' Obi-Wan Kenobi',
'mobile': ' 08877763212312',
'address ': ' Jl. Pemuda No.66 Bandung Selatan',
'product ': ' T-shirt Starwars ',
'quantity': ' 1',
'note ': ' size L'}]
推荐阅读
- javascript - 滚动播放 Html5 视频
- java - 将android studio连接到sql server
- python - 用 TensorFlow 中的线性代数帮助新手(排名 3 的张量)
- lua - coroutine.yield() 是否在 NodeMCU eLua 固件中将控制权返回给 SDK?
- java - 为什么`.read()`一个数字的方法返回不同的数字
- php - 为什么 textarea 在提交表单时显示旧内容?
- c# - 获取 Windows 用户信息
- git - Jenkins - 浅层克隆的影响
- javascript - 是否可以仅使用客户端发送电子邮件?
- visual-studio-code - VS Code http 链接未在 Web 浏览器中打开