如何在Python 3中使用cmp()函数?

66
我无法让Python 3中的cmp()命令正常工作。
以下是代码:
a = [1,2,3]
b = [1,2,3]
c = cmp(a,b)
print (c)

我遇到了一个错误:
Traceback (most recent call last):
  File "G:\Dropbox\Code\a = [1,2,3]", line 3, in <module>
    c = cmp(a,b)
 NameError: name 'cmp' is not defined

它的哪个方面出了问题? - DSM
6
你正在使用Python 2.x还是3.x?2.x中有cmp()函数,但3.x没有。由于print后面有括号,我怀疑你在使用3.x。 - Dietrich Epp
我正在使用3.x版本,抱歉,我已经更新了帖子,将输出放在其中。 - BenFire
9个回答

109

正如评论中所提到的,Python 3 中不存在 cmp。如果你真的需要它,你可以自己定义:

def cmp(a, b):
    return (a > b) - (a < b) 

这段内容摘自原始文档Python 3.0的最新功能。尽管不是没有用过,但需要使用它的情况相对较少,因此您可能需要考虑是否实际上它是您正在做的任何事情的最佳方法。


2
也许需要像这样转换布尔值:def cmp(a, b): return int(a > b) - int(a < b) - Oren
2
根据@Oren的评论,如果a和b是numpy变量,则(a>b)(a<b)变量可能是numpy.bool_类型。numpy.bool_类型不支持减法。使用bool(a>b)-bool(a<b)可以解决这个问题。 - Yohai Devir

14
在Python 3.x中,你可以使用import operator导入operator模块,并使用该模块的eq()lt()等方法,而不是使用cmp()

1
当需要符号时,最安全的选择可能是使用math.copysign函数:
import math
ang = -2
# alternative for cmp(ang, 0):
math.copysign(1, ang)

# Result: -1

特别是当ang的类型为np.float64时,由于'-'运算符的弃用。

import numpy as np

def cmp_0(a, b):
    return (a > b) - (a < b)

ang = np.float64(-2)
cmp_0(ang, 0)

# Result:
# DeprecationWarning: numpy boolean subtract, the `-` operator, is deprecated, 
# use the bitwise_xor, the `^` operator, or the logical_xor function instead.

"相反,可以使用以下代码:"
def cmp_0(a, b):
    return bool(a > b) - bool(a < b)

ang = np.float64(-2)
cmp(ang, 0)
# Result: -1

似乎对于 0 无效。 - theonlygusti

0

你可以使用这种更简单的方法

a=[1,2,3]
b=[1,2,3]
c=not(a!=b)
c
True

0

虽然在一般情况下,这些都是cmp()的良好替代品,但对于原始帖子给出的实际用例,肯定

a = [1,2,3]
b = [1,2,3]
c = a != b
print(c)

或者只是

a = [1,2,3]
b = [1,2,3]
print(a != b)

会工作得非常好。


0

在 @maxin 的回答中补充一点,在 Python 3.x 中,如果你想要比较两个元组列表 ab

import operator

a = [(1,2),(3,4)]
b = [(3,4),(1,2)]
# convert both lists to sets before calling the eq function
print(operator.eq(set(a),set(b))) #True

-1
如果a或b是类对象,则上述答案将出现编译错误,例如:a是类Clock:
  File "01_ClockClass_lab16.py", line 14, in cmp
    return (a > b) - (a < b)
TypeError: '>' not supported between instances of 'Clock' and 'Clock'

使用int()函数更改类型以消除错误:

def cmp(a, b):
    return (int(a) > int(b)) - (int(a) < int(b))  

10
你应该在自定义类中定义比较运算符,而不是将所有内容都转换为整数进行比较。 - Imperishable Night

-3

一种简单的方法是使用a - b并检查符号。

def cmp(a, b):
    return a - b

if a < b, negative

if a = b, zero

if a > b, positive

1
cmp 应该也适用于非数字类型,例如 str。对于与旧代码的正确互操作,函数真正只返回 -1、0 或 1 是很重要的。 - John La Rooy

-4

这个cmp()函数仅适用于 Python 2.x 版本,如果您尝试在版本3.x中使用它,会产生错误:

NameError: name 'cmp' is not defined
[Finished in 0.1s with exit code 1]

请看下面的代码:
a=60
b=90
print(cmp(a,b))

输出:

-1

在比较整数时,cmp() 函数只执行其参数的减法操作,即在本例中为 a-b。如果减法结果为负,则返回 -1,即 a<b;如果减法结果为正,则返回 1,即 a>b。

a=90
b=60
print(cmp(a,b))

输出:

1

再一次:

a="abc"
b="abc"
print(cmp(a,b))

输出:

0

当两个参数相等时,即a=b时,它返回0作为输出。在这里,我们传递了两个字符串类型的值。在这里,cmp()逐个比较两个字符串的字符,如果找到相同的字符,则返回0。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接