我注意到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递归,或者它是否会返回任意值。
答案 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
如果它们是相同的,那么它会尝试找到一个键,其中一个键或另一个键中缺少键(这称为characterizing the dict)
它执行第2步,无论是a, b
还是b, a
。如果其中任何一个为空,则假定两个词典都是相同的。
现在,我们将通过对字典特征的差异进行比较,得出实际的比较结果。
答案 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