Python使用的字符串比较技术

时间:2011-01-26 16:17:42

标签: python string comparison

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

例如,如果我提出print('abc' < 'bac'),我会True。我理解它比较了字符串中的相应字符,但是由于缺乏更好的术语,它还不清楚为什么还有更多,“权重”放在第一个字符串中的a小于b(第一个位置)而非a在第二个字符串(第二个位置)中小于b的事实。

8 个答案:

答案 0 :(得分:69)

来自docs

  

比较使用词典   订购:首先是前两项   比较,如果他们不同这一点   决定了结果   比较;如果他们是平等的,那么   接下来的两个项目进行比较,等等   在,直到任一序列为止   耗尽。

此外:

  

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

Python 2

  

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

举个例子:

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

一旦发现False小于a,就会返回结果b。其他项目不会进行比较(正如您可以看到的第二项:b&gt; 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)]

答案 1 :(得分:8)

Python字符串比较是词典:

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

  

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

因此,在您的示例中,'abc' < 'bac','a'以数字形式出现(小于)'b'(在ASCII和Unicode表示中),因此比较在那里结束。

答案 2 :(得分:7)

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

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

(2)第一个字符的重量大于第二个字符:'az'&lt; 'za'(语言是从左到右还是从右到左书写,或者boustrophedon是无关紧要的)

(3)如果用完要测试的字符,则较短的字符串小于较长的字符串:'foo'&lt; '食物'

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

答案 3 :(得分:3)

这是lexicographical ordering。它只是按字典顺序排列。

答案 4 :(得分:3)

另请参阅How do I sort unicode strings alphabetically in Python?,其中的讨论是关于Unicode整理算法(http://www.unicode.org/reports/tr10/)给出的排序规则。

回复评论

  

什么?如何定义除了从左到右的顺序?

由S.Lott撰写,在排序法语时有一个着名的反例。它涉及口音:实际上,人们可以说,在法语中,字母从左到右排序,从右到左排列。这是反例: 我们有e&lt; é和o&lt; ô,所以你会期望将cote,coté,côte,côté这两个词分类为cote&lt; coté&lt; côte&lt;的Côté。嗯,这不是发生的事情,事实上你有:cote&lt; côte&lt; coté&lt; côté,即如果我们删除“c”和“t”,我们得到oe&lt; ôe&lt; oé&lt; ôé,这是完全从右到左的排序。

最后一句话:你不应该谈论从左到右从右到左排序,而是关于前进向后排序。

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

实际上,Unicode考虑以逻辑顺序编码的字符串,而写入方向是在字形级别上发生的现象。换句话说,即使在单词שלום中,字母shin出现在lamed的右边,逻辑上它出现之前它。要对这个单词进行排序,首先要考虑的是胫骨,然后是lamed,然后是vav,然后是mem,这是前进顺序(虽然希伯来语是从右到左),而法语口音向后(虽然法语是从左到右书写的)。

答案 5 :(得分:2)

用于字符串比较的纯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 depends on the length
    # of the strings.
    return len(string1) < len(string2)

此函数与实际方法(Python 3.6Python 2.7)相当,但速度要慢很多。另请注意,实施并非完全&#34; pythonic&#34;并且仅适用于<比较。它只是为了说明它是如何工作的。我还没有检查它是否像combined unicode characters的Pythons比较一样。

更通用的变体是:

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 op(len(string1), len(string2))

答案 6 :(得分:1)

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

答案 7 :(得分:0)

下面是一个示例代码,用于按字典顺序比较两个字符串。

>>> s = "he exited through the Exit"
>>> re.sub(r"\b(exit)\b", lambda m: "'%s'"%m.group(1).upper(), s, flags=re.I)
"he exited through the 'EXIT'"

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

  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')