我有一套相当简单的要求。我有一个列表(长度为200万)的对象,每个对象有2个属性需要重新编码(其他属性不会更改)
ZERO ONE TWO ... TEN的值需要更改为其数值:1 2 ... 10
示例:
ONE MAIN STREET -> 1 MAIN STREET
BONE ROAD -> BONE ROAD
BUILDING TWO, THREE MAIN ROAD -> BUILDING 2, 3 MAIN ROAD
ELEVEN MAIN ST -> ELEVEN MAIN STREET
ONE HUNDRED FUNTOWN -> 1 HUNDRED FUNTOWN
显然有些数字没有改变,有些数字很奇怪。 完全可以预期
我可以用下面的内容来完成所有工作。我的问题是,是否有一种聪明的方法可以使这一切运行得更快?我想过制作一个list
dictionaries
,其中键是单词数字,值是数字,但我认为这不会有助于提高性能。或re.compile
每个正则表达式并将它们传递给此函数?有什么聪明的想法可以让它跑得更快吗?
def update_word_to_numeric(entrylist):
updated_entrylist = []
for theentry in entrylist:
theentry.addr_ln_1 = re.sub(r"\bZERO\b", "0", theentry.addr_ln_1)
theentry.addr_ln_1 = re.sub(r"\bONE\b", "1", theentry.addr_ln_1)
theentry.addr_ln_1 = re.sub(r"\bTWO\b", "2", theentry.addr_ln_1)
theentry.addr_ln_1 = re.sub(r"\bTHREE\b", "3", theentry.addr_ln_1)
theentry.addr_ln_1 = re.sub(r"\bFOUR\b", "4", theentry.addr_ln_1)
theentry.addr_ln_1 = re.sub(r"\bFIVE\b", "5", theentry.addr_ln_1)
theentry.addr_ln_1 = re.sub(r"\bSIX\b", "6", theentry.addr_ln_1)
theentry.addr_ln_1 = re.sub(r"\bSEVEN\b", "7", theentry.addr_ln_1)
theentry.addr_ln_1 = re.sub(r"\bEIGHT\b", "8", theentry.addr_ln_1)
theentry.addr_ln_1 = re.sub(r"\bNINE\b", "9", theentry.addr_ln_1)
theentry.addr_ln_1 = re.sub(r"\bTEN\b", "10", theentry.addr_ln_1)
theentry.addr_ln_2 = re.sub(r"\bZERO\b", "0", theentry.addr_ln_2)
theentry.addr_ln_2 = re.sub(r"\bONE\b", "1", theentry.addr_ln_2)
theentry.addr_ln_2 = re.sub(r"\bTWO\b", "2", theentry.addr_ln_2)
theentry.addr_ln_2 = re.sub(r"\bTHREE\b", "3", theentry.addr_ln_2)
theentry.addr_ln_2 = re.sub(r"\bFOUR\b", "4", theentry.addr_ln_2)
theentry.addr_ln_2 = re.sub(r"\bFIVE\b", "5", theentry.addr_ln_2)
theentry.addr_ln_2 = re.sub(r"\bSIX\b", "6", theentry.addr_ln_2)
theentry.addr_ln_2 = re.sub(r"\bSEVEN\b", "7", theentry.addr_ln_2)
theentry.addr_ln_2 = re.sub(r"\bEIGHT\b", "8", theentry.addr_ln_2)
theentry.addr_ln_2 = re.sub(r"\bNINE\b", "9", theentry.addr_ln_2)
theentry.addr_ln_2 = re.sub(r"\bTEN\b", "10", theentry.addr_ln_2)
updated_entrylist.append(theentry)
return updated_entrylist
也许这只是一个很好的方法。 “足够好”的评论对我也很好。)
答案 0 :(得分:5)
使用一个正则表达式而不是十个(我发现速度提高了3倍)会快得多:
def replace(match):
return {
"ZERO": "0",
"ONE": "1",
"TWO": "2",
"THREE": "3",
"FOUR": "4",
"FIVE": "5",
"SIX": "6",
"SEVEN": "7",
"EIGHT": "8",
"NINE": "9",
"TEN": "10",
}[match.group(1)]
pattern = re.compile(r"\b(ZERO|ONE|TWO|THREE|FOUR|FIVE|SIX|SEVEN|EIGHT|NINE|TEN)\b")
def update_word_to_numeric(entrylist):
updated_entrylist = []
for theentry in entrylist:
theentry.addr_ln_1 = pattern.sub(replace, theentry.addr_ln_1)
theentry.addr_ln_2 = pattern.sub(replace, theentry.addr_ln_2)
updated_entrylist.append(theentry)
return updated_entrylist
我使用鲜为人知的功能将re.sub
函数作为第二个参数:它将获取一个匹配对象并返回替换字符串。这样我们就可以查找替换字符串了。
我还使用re.compile
来预编译正则表达式,这也改善了时间,但没有那么大的变化。
答案 1 :(得分:2)
这是使用字典的方法:
s = '''
ONE MAIN STREET
BONE ROAD
BUILDING TWO, THREE MAIN ROAD
ELEVEN MAIN ST
ONE HUNDRED FUNTOWN
'''
d = {'ZERO':'0', 'ONE':'1', 'TWO':'2', 'THREE':'3', 'FOUR':'4',
'FIVE':'5', 'SIX':'6', 'SEVEN':'7', 'EIGHT':'8', 'NINE':'9',
'TEN':'10', 'ELEVEN':'11', 'TWELVE':'12'}
p = re.compile(r'\b(' + '|'.join(d.keys()) + r')\b')
r = p.sub(lambda x: d[x.group()], s)
print(r)
根据需要在字典中添加或删除条目。
答案 2 :(得分:1)
numbers = ["\bZERO\b", "\bONE\b", "\bTWO\b", "\bTHREE\b", "\bFOUR\b", "\bFIVE\b", "\bSIX\b", "\bSEVEN\b", "\bEIGHT\b", "\bNINE\b", "\bTEN\b"]
for theentry in entrylist:
for i, number in enumerate(numbers):
theentry.addr_ln_1 = re.sub(r"{}".format(number), "{}".format(i), theentry.addr_ln_1)
theentry.addr_ln_2 = re.sub(r"{}".format(number), "{}".format(i), theentry.addr_ln_2)