【问题标题】:How to replace words in a string using a dictionary mapping如何使用字典映射替换字符串中的单词
【发布时间】:2018-09-11 01:06:18
【问题描述】:

我有下面这句话

a = "you don't need a dog"

还有一本字典

dict =  {"don't": "do not" }

但是我不能使用字典来映射句子中的单词,使用下面的代码:

''.join(str(dict.get(word, word)) for word in a)

输出:

"you don't need a dog"

我做错了什么?

【问题讨论】:

  • “正确”是什么意思?
  • for word in a 您需要对字符串中的单词进行标记。遍历字符串将为您提供单个字符。
  • 查看stackoverflow.com/questions/2400504/…以获得最佳解决方案

标签: python string python-3.x dictionary


【解决方案1】:

所有答案都是正确的,但是如果您的句子很长并且映射字典很小,您应该考虑迭代字典的项目(键值对)并将 str.replace 应用于原始句子.

其他人建议的代码。每个循环需要 6.35 µs。

%%timeit

search = "you don't need a dog. but if you like dogs, you should think of getting one for your own. Or a cat?"
mapping =  {"don't": "do not" }

search = ' '.join([mapping.get(i, i) for i in search.split()])

让我们尝试使用 str.replace 代替。每个循环需要 633 ns。

%%timeit 

search = "you don't need a dog. but if you like dogs, you should think of getting one for your own. Or a cat?"
mapping =  {"don't": "do not" }

for key, value in mapping.items():
    search = search.replace(key, value)

让我们使用 Python3 列表推导。所以我们得到了最快的版本,每个循环需要 1.09 µs。

%%timeit 

search = "you don't need a dog. but if you like dogs, you should think of getting one for your own. Or a cat?"
mapping =  {"don't": "do not" }

search = [search.replace(key, value) for key, value in mapping.items()][0]

你看出区别了吗?对于您的短句,第一个和第三个代码的速度大致相同。但是句子(搜索字符串)越长,性能上的差异就越明显。

结果字符串是:

'你不需要狗。但如果你喜欢狗,你应该考虑给自己养一只。还是一只猫?'

备注: str.replace 也会替换长连接词中的出现。需要确保仅对完整单词进行替换。我想有 str.replace 的选项。另一个想法是使用正则表达式作为explained in this posting,因为它们也处理大小写。查找字典中的尾随空格不起作用,因为您不会在句子的开头或结尾找到匹配项。

【讨论】:

  • search = [search.replace(key, value) for key, value in mapping.items()][0] 如果您的映射字典有多个词,它将只返回第一个替换词。
【解决方案2】:

比你想象的要简单:

只需循环,如果 dict1 中有一个单词,则获取该键的值。

dict1 =  {"don't": "do not" }

a = "you don't need a dog"

data=a.split()

for i,j in enumerate(data):
    if j in dict1:
        data[i]=dict1[j]
print(" ".join(data))

输出:

you do not need a dog

【讨论】:

    【解决方案3】:

    你需要在' '上split(' ')你的句子——如果你只是迭代一个字符串,你就会迭代字符:

    a = "you don't need a dog"
    
    for word in a:  # thats what you are using as input to your dict-key-replace
        print(word) # the single characters are never matched, thats why yours does not work.
    

    输出:

    y
    o
    u
    
    d
    o
    n
    '
    t
    
    n
    e
    e
    d
    
    a
    
    d
    o
    g
    

    阅读How to debug small programs

    之后,阅读How to split a string into a list?或使用jpp的解决方案。

    【讨论】:

      【解决方案4】:

      这是一种方法。

      a = "you don't need a dog"
      
      d =  {"don't": "do not" }
      
      res = ' '.join([d.get(i, i) for i in a.split()])
      
      # 'you do not need a dog'
      

      说明

      • 永远不要在类之后命名变量,例如使用d 而不是dict。
      • 使用str.split 以空格分隔。
      • 无需将str 包裹在已经是字符串的值周围。
      • str.join 与 marginally better 一起使用列表推导式与生成器表达式。

      【讨论】:

      • 我们是否需要在join 中建立一个额外的列表?
      • 如果查找字典很短,遍历它的项然后将 str.replace 应用于搜索字符串不是更好吗?我想这比将长搜索字符串分成单词并遍历所有单词要好得多。
      • @Matthias,同意了。我建议您可以将其写下来作为替代解决方案。绝对是解决问题的有效方法。
      猜你喜欢
      • 2012-04-26
      • 1970-01-01
      • 2021-04-21
      • 2019-01-29
      • 1970-01-01
      • 1970-01-01
      • 2012-09-13
      • 2017-06-03
      • 2021-09-23
      相关资源
      最近更新 更多