[英]Python sort and sorted — How are lists of lists sorted precisely?
为了对元素列表中的列表进行排序,Python中使用了哪些精确规则? 这可以表示为'key'或'cmp'函数吗? 问题来自于需要考虑两件事: 长度和价值在他们的位置 。
sorted([
[ 0, 1, 2, 3 ], # 1st line: longer list
[ 0, 1 ], # 2nd line: shorter list
[ 0, 2 ] # 3rd line: suspected last
])
假设第二行在第一行之前排序是否安全? 假设第三行总是最后排序是否安全?
注意,这不是关于稳定性 ! 上述具体情况表现如上所述。 但是,那里的规则可以被认为是一般性的吗? python在这里适用的准确规则是什么?
依据以下定义Lexicographical Order (感谢Ashniwi):
为了比较不同长度的序列,较短的序列通常在末尾填充足够的“空白”(特殊符号被视为小于A的每个元素)。 这种比较不同长度序列的方法总是用在字典中。 然而,在组合学中,经常使用另一种惯例,其中较短的序列总是小于较长的序列。 这种词典顺序的变体有时被称为短序。
Python是否使用' shortlex order '。 除了实际例子之外,该假设的证明在哪里?
默认情况下, sorted
使用比较项的__lt__
方法。 根据Python文档,具有可比元素的列表按字典顺序进行比较。 所以,是的,语言保证在较短的字符串中将在较长的字符串之前排序。
从文档引用:
特别是,通过比较相应的元素,按字典顺序比较元组和列表。 这意味着要比较相等,每个元素必须比较相等,并且两个序列必须是相同类型并且具有相同的长度。
[1,2] == (1,2)
是假的,因为类型不一样)。 [1,2,x] <= [1,2,y]
与x <= y
具有相同的值)。 如果不存在相应的元素,则首先排序较短的集合(例如, [1,2] < [1,2,3]
为真)。 可以使用此函数表示对列表进行的基本比较:
def cmp(list_1, list_2):
length_1 = len(list_1)
length_2 = len(list_2)
min_length = min(length_1, length_2)
# Compare individual items till there's a different item found
for i in xrange(min_length):
if list_1[i] > list_2[i]:
return 1
elif list_1[i] < list_2[i]:
return -1
# All items were same so far, let's compare sizes.
if length_1 > length_2:
return 1
elif length_1 < length_2:
return -1
elif length_1 == length_2:
return 0
演示:
>>> lst = [[ 0, 1, 2, 3 ], [ 0, 1 ], [ 0, 2 ]]
>>> print sorted(lst) == sorted(lst, cmp=cmp)
True
相关的CPython代码供参考 :
/* Search for the first index where items are different */
for (i = 0; i < Py_SIZE(vl) && i < Py_SIZE(wl); i++) {
int k = PyObject_RichCompareBool(vl->ob_item[i],
wl->ob_item[i], Py_EQ);
if (k < 0)
return NULL;
if (!k)
break;
}
if (i >= Py_SIZE(vl) || i >= Py_SIZE(wl)) {
/* No more items to compare -- compare sizes */
Py_ssize_t vs = Py_SIZE(vl);
Py_ssize_t ws = Py_SIZE(wl);
int cmp;
PyObject *res;
switch (op) {
case Py_LT: cmp = vs < ws; break;
case Py_LE: cmp = vs <= ws; break;
case Py_EQ: cmp = vs == ws; break;
case Py_NE: cmp = vs != ws; break;
case Py_GT: cmp = vs > ws; break;
case Py_GE: cmp = vs >= ws; break;
default: return NULL; /* cannot happen */
}
if (cmp)
res = Py_True;
else
res = Py_False;
Py_INCREF(res);
return res;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.