【问题标题】:How many letter were changed in string字符串中更改了多少个字母
【发布时间】:2013-12-10 02:14:54
【问题描述】:

您好,我是编程新手,

我想知道有没有一个函数或方法可以让我们找出一个字符串中改变了多少个字母..

示例:

输入:

"Cold"

输出:

"Hold"

因此只更改了 1 个字母

或示例:

输入:

"Deer"

输出:

"Dial"

因此更改了 3 个字母

【问题讨论】:

  • 您是否必须考虑丢失/多余的字符?
  • 您要查找的内容称为 levenshtein 距离。我见过一个 Python 库和一个可以有效计算它的 Java 库。你必须去找他们,因为我没有给你的快速参考。
  • pypi.python.org/pypi/python-Levenshtein/0.11.1 -- 在实践中(不同的用例)我发现计算 levenshtein 比使用 Python 标准库 @987654326 简化计算差异要慢@函数。

标签: python string python-3.x


【解决方案1】:

我说得太早了。谷歌搜索的第一个结果:

https://pypi.python.org/pypi/python-Levenshtein/

这应该能够测量从一个字符串到另一个字符串所需的最少更改次数。

【讨论】:

    【解决方案2】:

    如果不需要考虑字符插入或删除,问题就简化为简单地计算字符串之间不同的字符数。

    由于您是编程新手,因此命令式程序应该是:

    def differences(string1,string2):
        i=0
        different=0
        for i in range(len(string1)):
            if string1[i]!=string2[i]:
                different= different+1
        return different
    

    更 Pythonic 的东西是:

    def differences(string1,string2):
        different=0
        for a,b in zip(string1,string2):
            if a!=b:
                different+= 1
        return different
    

    或者,如果您想充分发挥功能:

    def differences(string1,string2):
        return sum(map(lambda (x,y):x!=y, zip(string1,string2)))
    

    正如@DSM 所建议的,它相当于更易读的生成器表达式:

    def differences(string1,string2):
        return sum(x != y for x,y in zip(string1, string2))
    

    【讨论】:

    • 我认为最简单的惯用版本是sum(x != y for x,y in zip(s1, s2))
    • @DSM 我想使用理解而不是映射更常见,当然也更具可读性。感谢您的建议,您介意我将其添加到答案中吗?
    • 一点也不!虽然它在技术上是一个生成器表达式,而不是一个推导式,因为没有对象(列表或集合)正在构建。
    • @DSM 你是对的,当然。我从来不明白为什么 python 有列表 comprehensions 和生成器 expressions - 特别是因为这个概念是“列表理解”,在许多其他语言中,是懒惰评估的
    • @goncalopp 我认为您是对的,最好将它们都称为某种“理解”。但是生成器表达式是在添加生成器的同时添加到 Python 中的,并且使用了类似的机制。列表推导式已经在 Python 中出现了一段时间。所以这个新东西是根据它的实现细节来命名的。 Python 有列表推导、字典推导、集合推导和...生成器表达式?我希望他们只是称他们为“理解”;生成器表达式几乎是没有列表部分的列表推导! :-)
    【解决方案3】:

    使用 itertools 库如下(Python 3.x)

    from itertools import zip_longest
    def change_count(string1, string2):
        count = 0
        for i, (char1, char2) in enumerate(zip_longest(string1, string2)):
            if char1 != char2:
                count = count + 1
        return count        
    string1 = input("Enter one string: ")
    string2 = input("Enter another string: ")
    changed = change_count(string1, string2)
    print("Times changed: ", changed)
    

    【讨论】:

    • 哦,是的,itertools.izip_longest() 处理一个字符串与另一个字符串长度不同的情况!为此+1。但是你无缘无故使用enumerate(),我建议使用sum(ch0 != ch1 for ch0, ch1 in izip_longest(string1, string2))
    • 我不确定以这种方式处理不同长度的字符串是否有意义。假设你有“拨号”和“重拨”:大多数人会说有两个变化,但这个算法会很高兴地说有 6 个。
    【解决方案4】:

    查看 difflib 库,尤其是 ndiff 方法。注意:这对于所需的工作来说有点矫枉过正,但它非常适合查看两个文件之间的差异(您可以看到哪些是新的,哪些是更改的,等等)

    word1 = "Cold"
    word2 = "Waldo"
    i = 0
    differences = difflib.ndiff(word1, word2)
    for line in differences:
        if line[0] is not " ":
            i += 1
    print(i)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-03
      • 2020-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-09
      相关资源
      最近更新 更多