Python使用的字符串比较技术

我想知道Python是如何进行字符串比较的,更具体地说,当使用小于(<)或大于(>)的符号时,它是如何确定结果的。

例如,如果我把打印('abc'<'bac'),我会得到真实的。 我知道它比较了字符串中相应的字符,但是为什么还有更多的字符不清楚,为什么没有更好的术语呢,把“重量”放在a的第一个字符串小于b(第一个位置)的事实上,而不是a在第二个字符串(第二个位置)中小于b的事实。

从文档 :

比较使用词典排序:首先比较前两个项目,如果它们不同则确定比较的结果; 如果它们相等,则比较下两项,等等,直到任何一个序列被耗尽为止。

也:

字符串的字典排序使用Unicode代码点号来排列单个字符。

或在Python 2上 :

字符串的字典排序使用单个字符的ASCII排序。

举个例子:

 >>> 'abc' > 'bac' False >>> ord('a'), ord('b') (97, 98) 

一旦发现b小于b返回结果False 。 进一步的项目不作比较(你可以看到第二项: b > aTrue )。

注意大写和小写:

 >>> [(x, ord(x)) for x in abc] [('a', 97), ('b', 98), ('c', 99), ('d', 100), ('e', 101), ('f', 102), ('g', 103), ('h', 104), ('i', 105), ('j', 106), ('k', 107), ('l', 108), ('m', 109), ('n', 110), ('o', 111), ('p', 112), ('q', 113), ('r', 114), ('s', 115), ('t', 116), ('u', 117), ('v', 118), ('w', 119), ('x', 120), ('y', 121), ('z', 122)] >>> [(x, ord(x)) for x in abc.upper()] [('A', 65), ('B', 66), ('C', 67), ('D', 68), ('E', 69), ('F', 70), ('G', 71), ('H', 72), ('I', 73), ('J', 74), ('K', 75), ('L', 76), ('M', 77), ('N', 78), ('O', 79), ('P', 80), ('Q', 81), ('R', 82), ('S', 83), ('T', 84), ('U', 85), ('V', 86), ('W', 87), ('X', 88), ('Y', 89), ('Z', 90)] 

Python字符串比较是词典:

从Python文档: http : //docs.python.org/reference/expressions.html

字符串按字典顺序进行比较,使用其字符的内置函数ord()的结果。 Unicode和8位字符串在这种行为中是完全可互操作的。

因此,在你的例子中, 'abc' < 'bac' ,'a'在数字前面(小于)'b'(在ASCII和Unicode表示中),所以比较结束于此。

Python和几乎所有其他计算机语言都使用与在打印字典中查找单词时使用的(我希望)相同的原则:

(1)根据所涉及的人类语言,你有一个字符排序的概念:'a'<'b'<'c'等

(2)第一个字符比第二个字符更重要:'az'<'za'(不管语言是从左到右还是从右到左,或者重音是非常不相关的)

(3)如果用完字符测试,较短的字符串小于较长的字符串:'foo'<'food'

通常情况下,在计算机语言中,“字符顺序的概念”是相当原始的:每个字符都有一个与人类语言无关的数字ord(character) ,并使用该数字对字符进行比较和排序。 通常这种排序不适合用户的人类语言,然后你需要进入“整理”,一个有趣的话题。

这是一个词典排序 。 它只是把字典顺序的东西。

还要看看如何在Python中按字母顺序排序unicode字符串? 讨论的内容是关于Unicode排序算法给出的排序规则( http://www.unicode.org/reports/tr10/ )。

回复评论

什么? 除了从左到右,还可以定义排序吗?

由S.Lott在排序法语时有一个着名的反例。 它涉及口音:事实上,人们可以说在法语中,字母是从左到右排列的,从右到左排列。 这里是反例:我们有e <o和o <o,所以你可以期望cote,coté,côte,côté这个词被归类为cote <coté<côte<côté。 那么这不是什么事情,事实上你有:cote <côte<coté<côté,即如果我们删除“c”和“t”,我们得到oe <ôe<oé<ôé,这是完全正确的 – 左侧排序。

最后一句话:你不应该说从左到右从右到左的排序,而是前后排序。

事实上,有些语言是从右向左编写的,如果您认为阿拉伯语和希伯来语是从右到左排序的,您可能从图形的角度来看是正确的,但在逻辑层面上是错误的!

实际上,Unicode认为字符串是按照逻辑顺序编码的,而写入方向是在字形级别上发生的现象。 换句话说,即使在信件中,字母shin出现在lamed的右边, 逻辑上之前出现。 为了排序这个词,首先要考虑小腿,然后是腿,然后是vav,然后是MEM,这是前向排序(虽然希伯来语是从右到左写的),而法国口音是向后排序的(尽管法语是书面从左到右)。

字符串按 字典顺序进行比较,使用其字符的内置函数ord()的结果。 Unicode和8位字符串在这种行为中是完全可互操作的。

一个纯Python等价的字符串比较将是:

 def less(string1, string2): # Compare character by character for idx in range(min(len(string1), len(string2))): # Get the "value" of the character ordinal1, ordinal2 = ord(string1[idx]), ord(string2[idx]) # If the "value" is identical check the next characters if ordinal1 == ordinal2: continue # If it's smaller we're finished and can return True elif ordinal1 < ordinal2: return True # If it's bigger we're finished and return False else: return False # We're out of characters and all were equal, so the result is False return False 

这个函数相当于真正的方法( Python 3.6和Python 2.7 )慢得多。 另外请注意,实现并不完全是“pythonic”,只适用于<比较。 这只是为了说明它是如何工作的。 我还没有检查它是否像Pythons比较组合的Unicode字符 。

更一般的变体是:

 from operator import lt, gt def compare(string1, string2, less=True): op = lt if less else gt for char1, char2 in zip(string1, string2): ordinal1, ordinal2 = ord(char1), ord(char1) if ordinal1 == ordinal2: continue elif op(ordinal1, ordinal2): return True else: return False return False 

这里是一个示例代码,它按字典顺序比较两个字符串。

  a = str(input()) b = str(input()) if 1<=len(a)<=100 and 1<=len(b)<=100: a = a.lower() b = b.lower() if a > b: print('1') elif a < b: print( '-1') elif a == b: print('0') 

对于不同的输入,输出是 –

 1- abcdefg abcdeff 1 2- abc Abc 0 3- abs AbZ -1