PythonPython·

How to find similar strings with python?

投稿時間:2024-06-28 00:09:18閲覧数:206
専門記事
転載は出所を明記してください

Suppose that we have a string str together with a list of strings arr = [str1, str2, ... ]. How to find similar string of str in arr? To do this, we can calculate the similarity of str and elements in arr one by one. But how to calculate the degree of similarity between str and an element in arr? First, we need a measurement of the similarity of two strings. In fact, there are many methods that measure the similarity of strings. In this tutorial, we will use python to find similar strings of str.

In python, there are several packages that concern similarity of strings.

1. Difflib

The builtin module difflib is for comparing sequences. You can use the SequenceMatcher.ratio method to calculate the similarity. It returns a float in range [0, 1].

>>> from difflib import SequenceMatcher
>>> a='How to do syntax highlighting for code blocks in Nuxt?'
>>> b='How to setup PrismJS and Autoloader plugin with Nuxt 3?'
>>> SequenceMatcher(None, a, b).ratio()
0.3853211009174312
>>> SequenceMatcher(None, "abcd", "abcd").ratio()
1.0

The more similar two strings are, the closer to 1 the ratio is.

You can also use the get_close_matches method.

>>> from difflib import get_close_matches
>>> get_close_matches('appel', ['ape', 'apple', 'peach', 'puppy'])
['apple', 'ape']

>>> get_close_matches('manitori', ['manifold', 'torus', 'tori', 'differential'])
['tori', 'manifold']

However, this method can't be used for long strings comparsion. To compare long strings, you may need to split the strings.

>>> a='How to do syntax highlighting for code blocks in Nuxt?'
>>> b='How to setup PrismJS and Autoloader plugin with Nuxt 3?'
>>> c='Mathjax loads slow. How to load local JS file with Nuxt?'
>>> d='How to render math in Vue or Nuxt?'
>>> e='Nginx is installed but command not found'
>>> f='Django ImageField max_length error when uploading image'
>>> get_close_matches(a, [b,c,d,e,f])
[]

The difflib module is pure python, not a python c library. Thus, it is not the fastest way.

2. Python-levenshtein

Python-levenshtein package is a Python C extension module. It is used for fast computation of Levenshtein distance. Levenshtein distance is a metric measuring the similarity of two strings. The bigger Levenshtein distance is, the more different two strings are.

To install this package, use pip:

pip install python-levenshtein

The following are the official examples of python-levenshtein:

>>> import Levenshtein
>>> help(Levenshtein.ratio)
ratio(...)
    Compute similarity of two strings.

    ratio(string1, string2)

    The similarity is a number between 0 and 1, it's usually equal or
    somewhat higher than difflib.SequenceMatcher.ratio(), becuase it's
    based on real minimal edit distance.

    Examples:
    >>> ratio('Hello world!', 'Holly grail!')
    0.58333333333333337
    >>> ratio('Brian', 'Jesus')
    0.0

>>> help(Levenshtein.distance)
distance(...)
    Compute absolute Levenshtein distance of two strings.

    distance(string1, string2)

    Examples (it's hard to spell Levenshtein correctly):
    >>> distance('Levenshtein', 'Lenvinsten')
    4
    >>> distance('Levenshtein', 'Levensthein')
    2
    >>> distance('Levenshtein', 'Levenshten')
    1
    >>> distance('Levenshtein', 'Levenshtein')
    0

3. Jellyfish

Jellyfish is a Python library that supports multiple methods for strings comparsion, including Levenshtein distance. Moreover, it supports phonetic encoding. To install jellyfish, use pip:

pip install jellyfish

Using jellyfish to compute Levenshtein distance is much faster than pure Python implementations. Here is an example:

>>> a='How to do syntax highlighting for code blocks in Nuxt?'
>>> b='How to setup PrismJS and Autoloader plugin with Nuxt 3?'
>>> import jellyfish
>>> jellyfish.levenshtein_distance(a,b)
35

Note that the Levenshtein distance is sensitive to case, so remember to use lower() if you care about the case:

>>> jellyfish.levenshtein_distance('Nuxt','nuxt')
1
>>> jellyfish.levenshtein_distance('nuxt','nuxt')
0

>>> a='How can I define a metric for uniqueness of strings on Django model?'
>>> b='How to specify uniqueness for a tuple of field in a Django model'
>>> jellyfish.levenshtein_distance(a.lower(),b.lower())
36

Finally, it is difficult to see the difference between two strings by these numbers. Therefore, it is good to normalize the Levenshtein distance between 0 to 1:

def normalizedLevenshteinDistance(double levenshtein, String s1, String s2) {
    return levenshtein / max(s1.length(), s2.length());
}

Here are some examples:

>>> a='How can I define a metric for uniqueness of strings on Django model?'
>>> b='How to specify uniqueness for a tuple of field in a Django model'
>>> jellyfish.levenshtein_distance(a.lower(),b.lower())
36
>>> 36/max(len(a),len(b))
0.5294117647058824

>>> b='Django Unique Together (with foreign keys)'
>>> jellyfish.levenshtein_distance(a.lower(),b.lower())
52
>>> 52/max(len(a),len(b))
0.7647058823529411

>>> b='Django unique_together with a specifc filter (like: somefield=somevalue)'
>>> jellyfish.levenshtein_distance(a.lower(),b.lower())
59
>>> 59/max(len(a),len(b))
0.8194444444444444

We can see that the closer to 1 the result is, the more different two strings are.

コメント欄

まだコメントがありません。最初のコメントを投稿しましょう!

弦圈热门内容

cover

共工怒触不周山并非传说,考古发现证据,专家:夏朝不是第一王朝

《列子·汤问》:“共工氏与颛顼争为帝,怒而触不周之山,折天柱,地维绝,天倾西北,故日月星辰移焉;得不满东南,故百川水潦归焉。共工是中国古代神话传说中的水神。因未能与颛顼争夺皇位,愤而推倒周围群山,导致天竺覆灭。但实际上,共工并不是一个个体,而是古代共工强大部落的人格化。据《左传》记载,共工家早在黄帝时代就是一个善于治水的部落。然而在尧舜时期,共工一家却突然成为天下诸侯的祸害,被舜帝列为天下“四害”。与三苗一起被华夏部落联盟驱逐,共工一家被迫从黄河迁徙到幽州。"“在幽州共事”也得到考古证实。尧舜生活在中国原始社会末期的一个龙山文化时代,分为中原龙山文化和山东龙山文化两种类型,分别代表居住在中原的炎黄部落(尧舜)的后裔和山东东夷人的后裔。中原龙山文化和山东龙山文化之间的豫北窄黄河地带还有一种特殊的文化类型:后港二期文化。后港二期也属于龙山文化体系,但有自己的特点。但在夏初龙山文化向二里头文化过渡的过程中,豫北后港二期文化突然消失,而辽西则突然出现了夏家店低级文化,与燕山南部同期考古类型完全不同,但与后港二期文化有传承关系。这说明在姚舜禹部落向夏朝过渡的过程中,居住在豫北的一个部落迁徙到辽西 ...

cover

当一个人张嘴闭嘴都说这些话,大概率,他要坑你了

人情社会的本质,就是人搞人,人整人,人坑人。所有的人情世故,要么是为了自己谋求利益,要么是跟别人搞好关系,间接谋求利益,要么是算计别人。基本上,人情世故就是“人整人”的直接反映。要想在充满人情世故的社会当中生存,就需要我们具备一种本事——听得懂别人的言外之意。别人说什么,我们不仅要把表面的言语搞清楚,还需要把言语背后的深意搞清楚。如此,才能避免被人算计,避免被人套路。普通人之所以容易被人套路,就是因为他们只看表象,只听场面话,而无法透过现象看本质。当一个人张嘴闭嘴都说这些话,大概率,别人要坑你了。一、张嘴闭嘴都是“仁义道德”。在《水浒传》里边,有一个超级伪君子,及时雨宋江。他文不如吴用,武不如林冲,但他还是当了梁山之主,因为宋江足够虚伪,懂得忽悠人。宋江跟吴用坑了玉麒麟卢俊义,害得他家破人亡,逼得卢俊义不得不投靠梁山。对于被他害惨的卢俊义,宋江非但没有羞愧,还满嘴仁义道德,声称要为卢员外报仇雪恨,同时还要让卢员外当梁山之主。宋江说的这些话,听得卢俊义一愣一愣的。哪怕卢俊义知道是宋江等人坑了自己,他也不好说什么,也就心甘情愿入伙了,当了梁山二当家。江湖中,永远都不缺像宋江这样的人。他们一 ...

cover

秦始皇铜马车上的伞,才是真正的“先进”设计,可很多人却不知道

春秋战国时期,国与国之间勾心斗角、战争不断。本来势单力薄,存在感不强的秦国,在别的国家忙于战事的时候,一直在积蓄能量。随着不断地改革,秦国逐渐崛起,秦始皇最后统一了六国,成为天下霸主!秦始皇建立了我国历史上第一个统一王朝,而在此之前,秦王嬴政的成长史也值得关注。尤其是始皇帝的父亲到底是谁,有说是庄襄王,也有说是吕不韦的。今天,咱们就来聊一聊秦始皇。少年始皇帝话说,庄襄王嬴异人一开始在赵国做质子,后来进入了吕不韦的“圈套”,看上了吕不韦的小妾赵姬。赵姬聪明貌美,一下子就俘获了庄襄王的心,不久之后,赵姬就生下了嬴政。有些野史中就说,赵姬其实和吕不韦在一起时就怀有身孕,后来为了不引起怀疑,吃了让胎儿迟点出生的药物。可是,现代医学中都应该没有这样的药物,更别说当时了,至于真假无从查知。嬴政出生以后一直生活在赵国,吕不韦先是帮庄襄王逃离了赵国,留下了赵姬和嬴政母子二人在赵国。回到秦国不久,庄襄王就当上了秦国的君主,过上了潇洒的生活,而在吕不韦多次提醒下,他想起自己还有妻子和儿子滞留在赵国。最终,赵姬和嬴政回到秦国,而且赵姬还当上了王后,嬴政成了太子。庄襄王去世,嬴政接过王位,但是这一时期主要的吕 ...

零申报常见问题答疑

1、取得免税收入,可以零申报吗?不可以。办理增值税减免备案的纳税人应纳税额为零,但并不代表该纳税人可以零申报,而是应该向税务机关如实申报。2、当期未取得收入,可以零申报吗?如果没有取得销售收入,但是存在进项税额,若该纳税人因未发生销售穴理零申报,未抵扣进项税额会造成逾期抵扣而不能抵扣。正确方式是在对应的销售额栏次填写0,把当期已认证的进项税额填入申报表的进项税额栏次中,产生期末留抵税额在下期继续抵扣。3、取得未开票收入,可以零申报吗?不可以。如果纳税人违规进行零申报,不仅要补缴当期税款还要加收滞纳金,并处罚款,正确方式是该纳税人应填入未开票收入中,按规定缴纳当期税款。4、月销售额未达10万,可以零申报吗?不可以,小规模在享受国家税收优惠的同时,应该向税务机关如实申报。5、代开发票已预缴税款,可以零申报吗?不可以,虽然代开发票已经缴纳了税款,依然不能简单地做零申报处理。应该在规定栏目填写销售收入,系统会自动生成已经缴纳的税款进行冲抵。6、企业长期亏损,企业所得税可以零申报吗?企业的亏损是可以向以后五个纳税年度结转弥补的,如果做了零申报则第二年盈利就不能弥补以前年度亏损了,会造成企业损失。 ...

cover

宇宙之谜:当银河系缩至1米,整个宇宙究竟能有多小?

宇宙究竟有多大?这个问题在人类踏出地球之后便一直被探索。古代因科技所限,人们普遍相信地球是唯一的世界。古人对地球的认知相对浅薄,例如古埃及人认为地球是放在四只大象背上的平板,而这些大象则站在一只大龟上漂浮在海面上。在我国,也有大地如棋盘的说法。然而,在公元前6世纪,古希腊的毕达哥拉斯首次提出地球是球形的理论,这标志着人类对地球认知的重大突破。毕达哥拉斯的观点基于细致的观察:他发现月光不是月亮自身发出的光,而是反射太阳的光,并进一步观察到月面阴暗交界处的弧形光线,这种光只有在照射到球形物体上才会出现。由此推断月球为球形,进而推想地球及其他天体亦然。到了16世纪,随着世界航海的大发展,一些著名航海家开始寻找海外殖民地。其中,麦哲伦带领的船队历经万难于1519年9月出发,最终在1522年9月返回西班牙,但麦哲伦本人却因介入当地冲突而不幸身亡,仅剩少数船员完成环球航行,实证了地球是一个球体,终结了关于地球形状的争论。进入20世纪中期,人类进入了太空时代,人造卫星拍摄的地球照片直观地证明了地球的球形本质,苏联宇航员加加林成为首位亲眼目睹地球为球体的人类。经过计算,我们得知地球的质量约为5.97* ...

cover

西游记中神仙长生不老,为何还要吃蟠桃?孙悟空说出真相!

孙悟空的第一个人生目标是什么,当然是学习长生不老之术,从而跳出三界之外,不在五行之中,自己的性命自己把握,不再由地府阎王来管理,这就是他的目标。的确,在菩提老祖的方寸山学习之后,回到花果山的孙悟空,被牛头马面抓去地府,一点也不怕,还顺带把生死簿上自己的名字给划去了。为什么孙悟空从方寸山回来就什么都不怕了,根本原因还是在于菩提老祖说的那番话,对于孙悟空来说,可信度是百分百的,那就是因为菩提老祖传授了孙悟空躲避三灾利害的功法,从此以后,只要每500年躲过一次天灾利害,孙悟空就可以长生不老,不用再被阎王爷管了。对于孙悟空来说,这一定是当时心中,最有成就感的事情了,其实最开始孙悟空也没有想明白,为什么求道了之后还要躲避三灾厉害,于是就问菩提老祖:”师父啊,您是不是说错了,我尝闻道高德隆,是可以与天同寿的,水火既济,百病不生,怎么会弄出来一个‘三灾利害’?”菩提老祖就告诉他了,传授他的这个东西是非常之道,可以夺天地之造化,侵日月之玄机,主要还是要修炼成一个金丹(这一点后面孙悟空喝醉了之后,闯入到兜率宫时,有提到过,当时说的是得道以来,识破了内外相同之理,要炼金丹了),不过在丹成之后,就会鬼神难容 ...

cover

1961年毛主席和周总理大吵,主席反问一句话,两人对视后都发出苦笑

我们都知道,毛主席与周总理是一对完美的经典搭档,当他们一起为国家做事的时候,总是让人们很安心。尼克松曾经说:“如果没有毛泽东,中国革命这把火就燃烧不起来;而如果没有周恩来,这把火就会把一切都烧光,只剩下灰烬。”这句话充分地说明了毛主席和周总理他们之间的相处,很多时候他们一起商量事情,最后总是能圆满结束。总的来说,他们二人之所以能成为经典搭档,主要的原因还是他们的思想一致,都是为人民服务。而随着社会的发展,他们终于让人民当家作主,也实现了他们共同的目标,使国家繁荣昌盛。说起他们的相识,还是在第一次国共合作时期,那个时候他们只是见面聊了聊,就知道了对方的目标和自己一致。建国后,周恩来当总理,毛泽东当主席,他们一起商量国家大事,在私底下他们的友情更是坚不可摧。在1972年,周恩来被确诊为膀胱癌,毛主席对此深感担心,亲自指示成立医疗小组为周总理治疗,要知道当时毛主席的身体情况也不好。但毛主席还是挂念着周总理,并写信告诉周总理要注意身体,之后无论多忙都会询问周总理的情况。而另一边,周总理到了晚期深受病魔困扰,就连说话都咬字不清,但他仍然打电话关心毛主席的身体健康。但值得注意的是,再好的朋友也会有 ...

cover

为何有人说萝卜是结节的“催化剂”?想要远离结节,3类食物少吃

导语:现在人们在体检方面的意识逐渐提高,有不少人都会趁着休假的时候到医院里面检查一下身体。在体检报告单上,很有可能会出现某某结节的字样,现如今人体内出现结节的情况越来越普遍。我们身体里的结节也分为了良性和恶性,良性不会危害健康,但如果是恶性的结节,则有可能发展为癌症。一、为什么有人说白萝卜是结节的“催化剂”?人体的各个器官上都有可能出现结节,而且结节的数量也有区别,导致结节出现的原因是多样的,其中就和大家的饮食有关联。有些人认为,经常吃萝卜会促进结节的出现,这个说法完全没有依据。萝卜是冬季比较受大家欢迎的一种蔬菜,它的营养价值比较丰富,不仅有各种各样维生素,而且还能帮助我们的肠胃分泌胃液,促进消化。把萝卜和不同的肉类搭配起来炖汤喝,营养价值还会翻倍。更关键的是,萝卜当中的很多营养成分对于我们的身体来说还有抗癌的作用。二、想要远离结节,这3类食物少吃1、高碘食物每个人的身体对于微量元素都是有需求的,这些微量元素也包括了各种各样的矿物质,尽管需求量不高,但却不能少。平时在做饭的时候,肯定都会往饭菜里面加入食盐调味,现在大多数盐当中都添加了碘元素。这是一种人体所需要的元素,因为它的摄入可以帮 ...

cover

专家打开千年古墓后,居然发现了一桌残羹剩饭,谁留下的?

从郭沫若打开明定陵,让文物受到不必要的损失后,国家就规定不能在挖掘古墓。尽管郭沫若之后多次建议挖掘古墓,但都遭到了拒绝。看来,郭沫若经过明定陵突发性事故后根本没有得到教训。而郭沫若几次想挖掘古墓的举动也遭到了多方指责,究竟是为了研究历史,还是一己之私,谁也说不清楚。为了保护文物,考古专家不会主动去挖掘一座墓葬,就如大众好奇的秦始皇陵一样,专家虽然是因为挖掘技术而没有挖掘秦始皇陵,但研究秦始皇陵的专家和相关学者,均认为始皇陵不应该被挖掘,应该被好好保护。在专家保护下的古墓不会被挖掘,但那些没有被保护的古墓却存在危险。近年,在专家的被动挖掘下,被埋葬历史中的古墓带着世人对他的好奇一次次被发掘。1993年,在河北张家口市的宣化区下八里村里,专家对村民灌溉时意外发现的辽代地下古墓进行了考古发掘。此次考古发掘,专家一共出土了辽代十座古墓,经过证实这是张文藻张氏家族的墓葬群,古墓出土了具有极高艺术价值的壁画,以及陪葬文物。其中出土的数件家具给考古专家研究中国家具制作,工艺等提供了极高的价值信息,其中有两把木椅居然基本保存完好,虽然这两把木椅没有明清时期的简洁和华贵,但他粗中有细形成了自己独特的设计 ...