【问题标题】:Fast way to replace a string according to dict根据dict替换字符串的快速方法
【发布时间】:2016-05-08 02:28:15
【问题描述】:

我想根据字典替换一个很长的字符串。我的代码是这样的:

def rep(self, mystr, dict):
    new_pstr = ''
    for char in mystr:
        try:
            new_pstr += dict[char]
        except:
            continue
    return new_pstr

这段代码没有我预期的那么快。也许没有循环,它会更快。但我不知道该怎么做。最后但同样重要的是,我不能一起替换所有相同的字符,每次我应该只替换一个字符。因此,替换功能可能不是我的选择。为了更清楚,我举个例子:

如果d = {'A':'C', 'C':'B'}mystr = 'AC',那么new_pstr = 'CB'

(如果你的方式返回我'BB',这不是我所期望的)

实际上,我的字典是这样的:

d = {u'q': [u'k'], u'v': [u'v'], u'e': [u'e'], u'\xe7': [u'\xe7'], u'\xe9': [u'e'], u'h': [u'y'], u'j': [u'z'], u'o': [u'u'], u'\xf1': [u'g'], u'i': [u'i'], u'\u015f': [u's'], u'\xf6': [u'u'], u'x': [u'x'], u'\xfc': [u'v'], u'\u011f': [u'g']}

我的字符串是这样的:

str = "tériniñ yiriklişip kétişi havadiki nemlikniñ tövenlep ketkenlikidin bolup ، bu vaqitta tére téximu qurğaqlişip kétidu ، tériniñ ilastikiliqi acizlap ، xünük bolup qalidu. şuña xanim – qizlar bundaq vaqitta tére qurğaqlişişniñ aldini alidiğan çare– tedbirlerni qolliniş kérek. nemlikni saqlaşta yuquri dericilik su toluqlaş yüzlüki، hesel ve örük méğizi méyiğa muvapiq miqdarda un arilaşturup melhem qilip yüzge çaplap bers e، yaki nemxuşluqi yuquri bolğan tére nemleştürüş vazilin méyi sürüp berse، qurğaq térige su toluqlaşqa paydiliq."

我使用 try.. except ... 的原因是因为我的代码有时会返回类似 UnicodeEncodeError: 'ascii' codec can't encode character u'\xe7' in position 2: ordinal not in range(128)

的错误

【问题讨论】:

  • 有什么理由不使用string.translate()
  • 使用数组追加和连接,而不是python中的字符串连接。
  • 与问题无关,但不要使用dict或其他内置类型作为变量名,mydict会更符合mystr
  • 您为什么需要删除字典中不存在的字符? (这就是except: continue 正在做的事情)
  • @neoyghur,你真的有多个字符作为值吗?

标签: python string performance replace


【解决方案1】:

咨询此Tutorial。它可能会帮助你。

translate() 方法返回一个字符串的副本,其中所有字符都已使用 table 翻译(由 string 模块中的 ma​​ketrans() 函数构造) ,可选择删除字符串 deletechars 中找到的所有字符。

示例代码:

以下是从字符串中删除“x”和“m”字符的示例:

#!/usr/bin/python

from string import maketrans   # Required to call maketrans function.

intab = "aeiou"
outtab = "12345"
trantab = maketrans(intab, outtab)

str = "this is string example....wow!!!";
print str.translate(trantab, 'xm')

这将产生以下结果 -

th3s 3s str3ng 21pl2....w4w!!!

此代码的source

【讨论】:

  • 我的 dict 包含 unicode 字符,所以我不能使用 maketrans 函数。
  • 哦,好吧,对不起,我不知道那部分。
【解决方案2】:

您似乎想要做的是将字符更改为等效的 ascii,Unidecode lib 将为您完成此操作,您需要对字符串进行解码并将其传递给unidecode.unidecode

In [8]: s = "tériniñ yiriklişip kétişi havadiki nemlikniñ tövenlep ketkenlikidin bolup ، bu vaqitta tére téximu qurğaqlişip kétidu ، tériniñ ilastikiliqi acizlap ، xünük bolup qalidu. şuña xanim – qizlar bundaq vaqitta tére qurğaqlişişniñ aldini alidiğan çare– tedbirlerni qolliniş kérek. nemlikni saqlaşta yuquri dericilik su toluqlaş yüzlüki، hesel ve örük méğizi méyiğa muvapiq miqdarda un arilaşturup melhem qilip yüzge çaplap bers e، yaki nemxuşluqi yuquri bolğan tére nemleştürüş vazilin méyi sürüp berse، qurğaq térige su toluqlaşqa paydiliq."

In [9]: unidecode.unidecode(s.decode("utf-8"))
Out[9]: 'terinin yiriklisip ketisi havadiki nemliknin tovenlep ketkenlikidin bolup , bu vaqitta tere teximu qurgaqlisip ketidu , terinin ilastikiliqi acizlap , xunuk bolup qalidu. suna xanim - qizlar bundaq vaqitta tere qurgaqlisisnin aldini alidigan care- tedbirlerni qollinis kerek. nemlikni saqlasta yuquri dericilik su toluqlas yuzluki, hesel ve oruk megizi meyiga muvapiq miqdarda un arilasturup melhem qilip yuzge caplap bers e, yaki nemxusluqi yuquri bolgan tere nemlesturus vazilin meyi surup berse, qurgaq terige su toluqlasqa paydiliq.'

或者如果你有多个字符作为值,这是你自己的逻辑的一个更快的工作版本:

In [27]: from itertools import chain
In [28]: d = {k:v[0] for k,v in d.items()}
In [29]:  "".join([d[ch] if ch in d else ch for ch in chain.from_iterable(s)])
Out[29]: 'terinig yiriklisip ketisi yavadiki nemliknig tuvenlep ketkenlikidin bulup ، bu vakitta tere teximu kurgaklisip ketidu ، terinig ilastikiliki acizlap ، xvnvk bulup kalidu. suga xanim – kizlar bundak vakitta tere kurgaklisisnig aldini alidigan çare– tedbirlerni kullinis kerek. nemlikni saklasta yukuri dericilik su tuluklas yvzlvki، yesel ve urvk megizi meyiga muvapik mikdarda un arilasturup melyem kilip yvzge çaplap bers e، yaki nemxusluki yukuri bulgan tere nemlestvrvs vazilin meyi svrvp berse، kurgak terige su tuluklaska paydilik.'

str.translate与unicode一起使用的正确方法是使用字符的ord

table =({ord(k):ord(ch) for k ,v in d.items() for ch in v})

s.translate(table)

【讨论】:

    【解决方案3】:

    我通过结合@Padraic Cunningham @PRVS 的答案得到最终答案,这个版本比我的原始代码快 100 倍。

     new_d = {ord(k): ord(v[0]) for k, v in d.items()} # ord for Unicode characters
     mystr.translate(d)
    

    如果您的代码没有任何 Unicode 字符,请查看@PRVS 答案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-14
      • 2014-04-29
      • 2017-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多