【发布时间】:2021-09-12 19:45:42
【问题描述】:
我正在将一些代码从 Python 2 转换为 Python 3。我有一个元组列表,其中每个元组包含一个数字元组和一组数字。这是一个小例子:
l1_python2 = [
((8, 6), Set([1, 2, 3, 4, 5, 6, 7, 8, 9])),
((8, 7), Set([1, 2, 3, 4, 5, 6, 7, 8, 9])),
((0, 3), Set([1, 2, 5, 6, 7, 9])),
((0, 4), Set([1, 2, 5, 6, 7, 9])),
((0, 5), Set([1, 2, 5, 6, 7, 9])),
((0, 6), Set([1, 2, 5, 6, 7, 9])),
((0, 7), Set([1, 2, 5, 6, 7, 9])),
((0, 8), Set([1, 2, 5, 6, 7, 9])),
((1, 0), Set([1, 2, 5, 6, 7, 9])),
((8, 8), Set([1, 2, 3, 4, 5, 6, 7, 8, 9])),
((5, 3), Set([1, 2, 3, 4, 5, 6, 7, 8, 9])),
((5, 4), Set([1, 2, 3, 4, 5, 6, 7, 8, 9])),
((5, 5), Set([1, 2, 3, 4, 5, 6, 7, 8, 9])),
((5, 6), Set([1, 2, 3, 4, 5, 6, 7, 8, 9])),
]
l1_python3 = [
((8, 6), {1, 2, 3, 4, 5, 6, 7, 8, 9}),
((8, 7), {1, 2, 3, 4, 5, 6, 7, 8, 9}),
((0, 3), {1, 2, 5, 6, 7, 9}),
((0, 4), {1, 2, 5, 6, 7, 9}),
((0, 5), {1, 2, 5, 6, 7, 9}),
((0, 6), {1, 2, 5, 6, 7, 9}),
((0, 7), {1, 2, 5, 6, 7, 9}),
((0, 8), {1, 2, 5, 6, 7, 9}),
((1, 0), {1, 2, 5, 6, 7, 9}),
((8, 8), {1, 2, 3, 4, 5, 6, 7, 8, 9}),
((5, 3), {1, 2, 3, 4, 5, 6, 7, 8, 9}),
((5, 4), {1, 2, 3, 4, 5, 6, 7, 8, 9}),
((5, 5), {1, 2, 3, 4, 5, 6, 7, 8, 9}),
((5, 6), {1, 2, 3, 4, 5, 6, 7, 8, 9}),
]
在 Python 2 中排序的代码如下:
l1_python2.sort(
lambda a, b: len(a[1]) > len(b[1])
and 1
or len(a[1]) < len(b[1])
and -1
or a[0] > b[0]
and 1
or a[1] < b[1]
and -1
or 0
)
得到的排序列表是:
[
((0, 3), Set([1, 2, 5, 6, 7, 9])),
((0, 4), Set([1, 2, 5, 6, 7, 9])),
((0, 5), Set([1, 2, 5, 6, 7, 9])),
((0, 6), Set([1, 2, 5, 6, 7, 9])),
((0, 7), Set([1, 2, 5, 6, 7, 9])),
((0, 8), Set([1, 2, 5, 6, 7, 9])),
((1, 0), Set([1, 2, 5, 6, 7, 9])),
((8, 6), Set([1, 2, 3, 4, 5, 6, 7, 8, 9])),
((8, 7), Set([1, 2, 3, 4, 5, 6, 7, 8, 9])),
((8, 8), Set([1, 2, 3, 4, 5, 6, 7, 8, 9])),
((5, 3), Set([1, 2, 3, 4, 5, 6, 7, 8, 9])),
((5, 4), Set([1, 2, 3, 4, 5, 6, 7, 8, 9])),
((5, 5), Set([1, 2, 3, 4, 5, 6, 7, 8, 9])),
((5, 6), Set([1, 2, 3, 4, 5, 6, 7, 8, 9])),
]
我理解(或认为我理解)这是按集合长度和集合比较排序的。我一直在尝试转换为 Python 3,但没有运气。我首先尝试了这个:
l1_python3.sort(
key=(
lambda a, b: len(a[1]) > len(b[1])
and 1
or len(a[1]) < len(b[1])
and -1
or a[0] > b[0]
and 1
or a[1] < b[1]
and -1
or 0
)
)
这给出了一个错误,它缺少一个必需的位置参数 b,这是有道理的。然后我尝试了这个:
l1_python3.sort(
key=(
lambda a: len(a[0][1]) > len(a[1][1])
and 1
or len(a[0][1]) < len(a[1][1])
and -1
or a[0][1] > a[1][1]
and 1
or a[0][1] < a[1][1]
and -1
or 0
)
)
但这会返回一个类型错误,即“int”类型的对象没有 len()。我也尝试了其他一些东西,但它们通常根本不排序。谁能帮帮我?
谢谢!
【问题讨论】:
-
@Carcigenicate 他们实际上是这样做的,因为在 Python 中
and和or返回最后一个操作数(或类似的东西),并不总是True/False。因此它根据其他操作数返回 -1、1 或 0 -
@Holt 我知道短路,但 sort
key参数不接受 1,-1,0 作为返回 afaik。它需要一个布尔值,在这种情况下1、-1和True是相同的。它是一个接受有符号数字的比较器,但这是不同的。 -
@Carcigenicate 啊,是的,但是你应该说你说的是 Python 3 版本,因为在 Python 2 版本中,它使用了比较器(我猜)。
-
@Holt 这可能是真的。我对 2 没有足够的经验,可能会解释行为的差异(编辑:2 的
sort有一个接受替代行为的cmp参数)。 -
Python 2
sort()期望为cmp一个接受 2 个值并返回-1、0、1的函数,具体取决于哪个更大。 Python 3 期望key()接受一个值并返回它应该作为排序依据的值的函数。在 bytes.com 上有 Raymond HeItinger 的配方,用于将一种转换为另一种。谷歌python cmp2key。functools模块中有类似的东西。
标签: python python-3.x sorting python-2.x