提问人:davelupt 提问时间:1/27/2011 最后编辑:Karl Knechteldavelupt 更新时间:5/19/2023 访问量:158763
字符串是如何比较的?
How are strings compared?
问:
我想知道 Python 如何进行字符串比较,更具体地说,当使用小于或大于运算符时,它如何确定结果。<
>
例如,如果我把我得到.我知道它比较了字符串中的相应字符,但是由于缺乏更好的术语,为什么不清楚为什么在第一个字符串中小于(第一个位置)的事实上放置了更多的“权重”,而不是小于第二个字符串(第二个位置)的事实。print('abc' < 'bac')
True
a
b
a
b
当字符串包含数字的表示形式时,许多人会问这个问题,并希望通过数值比较数字。直接的解决方案是首先转换值。请参阅 如何将字符串解析为 float 或 int?。如果列表或其他集合中有多个数字,请参阅如何在列表、字典等中收集重复计算的结果(或复制修改了每个元素的列表)?
如果您尝试比较包含数字序列的字符串,将数字视为数字(有时称为“自然排序”),请参阅是否有用于字符串自然排序的内置函数?。
答:
从文档中:
比较使用词典 排序:先订购前两件 进行比较,如果它们不同,则 确定 比较;如果它们相等,则 接下来的两个项目进行比较,依此类推 on,直到任一序列 用尽。
也:
字符串的词典排序使用 Unicode 码位编号对单个字符进行排序。
或在 Python 2 上:
字符串的词典排序对单个字符使用 ASCII 排序。
举个例子:
>>> 'abc' > 'bac'
False
>>> ord('a'), ord('b')
(97, 98)
一旦发现小于 ,将立即返回结果。其他项目不进行比较(如第二项所示:> 是 )。False
a
b
b
a
True
请注意小写和大写:
>>> [(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)]
具体来说,这会产生 、 等的结果,包括所有计算结果,因为从 a 到 z 的所有小写字符的码位数都高于所有大写字符。'a' > 'A'
'b' > 'B'
'a' > 'Z'
True
评论
'abc' < 'abcd'
"24" > 40
True
ord("2")
= 50
Python 字符串比较是字典式的:
来自 Python 文档: http://docs.python.org/reference/expressions.html
使用字符串字符的数字等价物(内置函数 ord() 的结果)对字符串进行字典比较。Unicode 和 8 位字符串在此行为中是完全可互操作的。
因此,在您的示例中,“a”在数字上位于(小于)“b”之前(在 ASCII 和 Unicode 表示中),因此比较就到此结束。'abc' < 'bac'
评论
这是词典排序。它只是按字典顺序排列。
评论
'a' > 'z'
True
'a' > 'Z'
False
使用字符串字符的数字等价物(内置函数 ord() 的结果)对字符串进行字典比较。Unicode 和 8 位字符串在此行为中是完全可互操作的。
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 < ô,所以你会期望 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 出现在跛脚的右侧,从逻辑上讲,它出现在它之前。要对这个词进行排序,首先要考虑胫骨,然后是跛脚,然后是 vav,然后是 mem,这是向前排序(尽管希伯来语是从右到左写的),而法语口音是向后排序的(尽管法语是从左到右写的)。
字符串比较的纯 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
# It's not equal so we're finished at this index and can evaluate which is smaller.
else:
return ordinal1 < ordinal2
# 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.6 和 Python 2.7),只是速度慢得多。另请注意,该实现并不完全是“pythonic”,仅适用于比较。这只是为了说明它是如何工作的。我还没有检查它是否像 Python 比较组合的 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(char2)
if ordinal1 == ordinal2:
continue
else:
return op(ordinal1, ordinal2)
return op(len(string1), len(string2))
评论
False
string1
string2
doggy
dog
if len(string1) < len(string2): return True
return False
False
True
False
string1
False
string2
True
return len(string1) < len(string2)
else: return op(ordinal1, ordinal2)
elif op(ordinal1, ordinal2): return True else: return False
else if
评论
sorted(range(10), key=lambda i: i ^ 123)
sorted('How else can ordering be defined other than left-to-right?'.split(), key= lambda s: s[::-1])