Python 字典中 “<” 的含义是什么?

17 投票
2 回答
912 浏览
提问于 2025-04-18 03:33

我注意到Python允许我这样做:

>>> {1: "foo"} < {2: "bar"}
True

它也允许我对列表、双端队列等做同样的事情。那么在Python中,<这个符号在字典上有什么特别的含义呢?

一般来说,我在哪里可以找到关于<在任何集合类型上的含义呢?大多数情况下,这似乎在文档中找不到。例如:

>>> help(dict.__cmp__)

Help on wrapper_descriptor:

__cmp__(...)
    x.__cmp__(y) <==> cmp(x,y)

>>> help(cmp)

Help on built-in function cmp in module __builtin__:

cmp(...)
    cmp(x, y) -> integer

    Return negative if x<y, zero if x==y, positive if x>y.

我问这个是因为我有一个元组列表,格式是(int, dict)。我想根据第一个元素对这个数组进行排序,但如果两个项目的第一个元素相同,我就不在乎第二个元素。我想知道myArray.sort()在这种情况下是否会做一些复杂的事情,比如递归遍历字典,还是说它只是返回一个任意的值。

2 个回答

0

就像@thefourtheye的回答那样。

用Python写的,可以这样理解:

def dict_compare(a, b):
    if len(a) != len(b):                # STEP 1: compare by length
        return -1 if len(a) < len(b) else 1

    res = 0
    akey, aval = characterize(a, b)     # Find first k, v that a[k] != b[k]
    bkey, bval = characterize(b, a)
    if akey is None:  # if no difference
        return 0
    if bkey is not None:               # STEP 2: compare by key
        res = cmp(akey, bkey)
    if res == 0 and bval is not None:  # STEP 3: compare by value
        res = cmp(aval, bval)
    return res

其中,characterize这个函数大概是这样的:

def characterize(a, b):
    """Find the first k that a[k] != b[k]"""
    akey, aval = None, None
    for k, v in a.items():
        if akey < k:
            continue
        if (k not in b) or (a != b[k]):
            akey, aval = k, v

    return akey, aval
15

引用自比较文档,

元组和列表

元组和列表的比较是通过比较它们对应的元素来进行的。这意味着要想两个序列相等,每个元素都必须相等,并且这两个序列必须是同一种类型且长度相同。

如果不相等,那么它们的顺序是根据第一个不同的元素来决定的。例如,比较[1,2,x]和[1,2,y]的结果和比较x和y的结果是一样的。如果对应的元素不存在,较短的序列会排在前面(比如说,[1,2] < [1,2,3])。

字典

字典只有在它们的排序后的(键,值)列表相等时才算相等。(这个实现方式很高效,不需要构建列表或排序。)除了相等的结果外,其他结果会一致处理,但没有其他定义。(早期版本的Python [在2.7.6之前]使用排序后的(键,值)列表进行字典的字典序比较,但这在比较相等时开销很大。更早的版本仅通过身份比较字典,但这让人感到意外,因为人们期望能通过与{}比较来测试字典是否为空。)

另外,可以查看文档中的这一部分,专门讲了序列类型之间以及与其他类型的比较,

序列对象可以与其他相同类型的对象进行比较。比较是通过字典序进行的:首先比较前两个元素,如果它们不同,就决定了比较的结果;如果相等,就比较下两个元素,依此类推,直到其中一个序列比较完。如果要比较的两个元素本身也是相同类型的序列,则会递归进行字典序比较。如果两个序列的所有元素都相等,则这两个序列被认为是相等的。如果一个序列是另一个序列的初始子序列,则较短的序列被认为是较小的(更小的)序列。字符串的字典序比较使用的是字符的ASCII顺序。

需要注意的是,比较不同类型的对象是合法的。结果是确定的,但任意的:类型是按名称排序的。因此,列表总是小于字符串,字符串总是小于元组,等等。(不同类型对象的比较规则不应被依赖;它们可能会在未来的语言版本中发生变化。)混合数字类型的比较是根据它们的数值进行的,所以0等于0.0,等等。

根据Python 2.7源代码,实际的字典比较过程如下:

  1. 首先比较键的长度。(如果第一个字典的键更少,返回-1;如果第二个字典的键更少,返回1

  2. 如果长度相同,就尝试找一个键,看看在另一个字典中是否缺少这个键或者这个键的值不同(这叫做描述字典

  3. 执行第2步,无论是还是b, a。如果其中一个字典是空的,那么两个字典被认为是相等的。

  4. 现在,从描述字典中得到的差异将被比较,以得出实际的比较结果。

撰写回答