“<”是什么意思对于Python词典?

时间:2014-04-21 06:35:36

标签: python python-2.7 python-internals

我注意到Python让我这样做:

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

它让我对列表,deques等做同样的事情。<在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()是否会做一些复杂的事情,包括在这种情况下通过dicts递归,或者它是否会返回任意值。

2 个答案:

答案 0 :(得分:15)

comparison文档引用,

元组和列表

  

使用相应元素的比较,按字典顺序比较元组和列表。这意味着要比较相等,每个元素必须比较相等,并且两个序列必须是相同的类型并具有相同的长度。

     

如果不相等,则序列的排序与其第一个不同的元素相同。例如,cmp([1,2,x],[1,2,y])返回与cmp(x,y)相同的值。如果相应的元素不存在,则首先排序较短的序列(例如,[1,2]&lt; [1,2,3])。

字典

  

映射(字典)比较相等,当且仅当它们的排序(键,值)列表比较相等时。 (实现有效地计算它,而不构造列表或排序。)除了相等之外的结果一致地解决,但没有另外定义。 (早期版本的Python [在2.7.6之前]使用了排序(键,值)列表的字典比较,但这对于比较相等的常见情况来说非常昂贵。甚至更早版本的Python仅通过标识比较字典,但这引起了惊喜,因为人们希望能够通过将字典与{}进行比较来测试字典的空虚。)

另外,找到this part of the documentation,它专门将序列类型与自身和其他类型进行比较,

  

可以将序列对象与具有相同序列类型的其他对象进行比较。比较使用词典排序:首先比较前两个项目,如果它们不同,则确定比较的结果;如果它们相等,则比较接下来的两个项目,依此类推,直到任一序列用完为止。如果要比较的两个项本身是相同类型的序列,则递归地执行词典比较。如果两个序列的所有项比较相等,则认为序列相等。如果一个序列是另一个序列的初始子序列,则较短的序列是较小的(较小的)序列。字符串的字典排序使用单个字符的ASCII排序。

     

请注意,比较不同类型的对象是合法的。结果是确定性的但是随意的:类型按其名称排序。因此,列表总是小于字符串,字符串总是小于元组等。(不应依赖于比较不同类型对象的规则;它们可能会在将来的语言版本中更改。)混合数字类型根据其数值进行比较,因此0等于0.0等

根据Python 2.7 source code的实际字典比较,就像这样

  1. 首先比较键的长度。 (如果第一个键较小,则返回-1,如果第二个键较小,则返回1

  2. 如果它们是相同的,那么它会尝试找到一个键,其中一个键或另一个键中缺少键(这称为characterizing the dict

  3. 它执行第2步,无论是a, b还是b, a。如果其中任何一个为空,则假定两个词典都是相同的。

  4. 现在,我们将通过对字典特征的差异进行比较,得出实际的比较结果。

答案 1 :(得分: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