Python 比较字符串和数字,解码无线电呼号

Python 比较字符串和数字,解码无线电呼号,python,sorting,Python,Sorting,我有一种感觉,这个问题的核心概念可能是一个重复的问题,但我找不到它 我有一大堆无线电呼号,想找到它的原产国 我尝试进行基本的比较以找到国家/地区,但Python对数字和字符的排序方式与呼号的排序方式不同: 在Python中,在呼号约定中,这将是False 我可以从更改Python的顺序吗。。。7

我有一种感觉,这个问题的核心概念可能是一个重复的问题,但我找不到它

我有一大堆无线电呼号,想找到它的原产国

我尝试进行基本的比较以找到国家/地区,但Python对数字和字符的排序方式与呼号的排序方式不同:

在Python中,在呼号约定中,这将是
False


我可以从
更改Python的顺序吗。。。7<8<9
。。。X

sorted()
这样的函数允许您提供自己的
cmp
函数-您只需实现它。但是你可以自由地说,数字比字母更重要,而通常的排序算法将处理其余部分


如果您只想比较而不是排序,那么您必须为它实现自己的功能。从两个字符串中逐个字符,并据此做出决定。

您可以创建一个
dict
将字符按“正确”顺序映射到它们的位置,然后比较位置列表:

import string
order = {e: i for i, e in enumerate(string.ascii_uppercase + string.digits)}
positions = lambda s: [order[c] for c in s]

def cmp_callsign(first, second):
    return cmp(positions(first), positions(second))  # (cmp removed in Python 3)
用法:

>>> positions("ZR1")
[25, 17, 27]
>>> cmp("ZR1", "ZRA")  # normal string comparison
-1
>>> cmp_callsign("ZR1", "ZRA")  # callsign comparison
1
>>> sorted(["AR1", "ZR1", "ZRA"], key=positions)
['AR1', 'ZRA', 'ZR1']
要使此比较自动进行,您还可以创建
类呼号
,并相应地重写
\uuuu cmp\uuuu
\uuuu eq\uuu
\uu lt\uuu
方法:

class Callsign:
    def __init__(self, code):
        self.code = code
    def __lt__(self, other):
        return positions(self.code) < positions(other.code) 

a, b, c = Callsign("ZRA"), Callsign("ZR1"), Callsign("ZR9")
print(a < b < c)  # True
print(a < c < b)  # False
class呼号:
定义初始化(自我,代码):
self.code=代码
定义(自身、其他):
返回位置(自身代码)<位置(其他代码)
a、 b,c=呼号(“ZRA”)、呼号(“ZR1”)、呼号(“ZR9”)
打印(a
您只需编写自己的键函数,如下所示:

def radio_order(s):
    def character_sorting_order(a):
        if a.isnumeric():
            return ord('z') + 1 + int(a)
        else:
            return ord(a)
    return tuple(map(character_sorting_order, s))

print('z1' < 'zA' < 'za') # native python ordering
print(radio_order('zA') < radio_order('za') < radio_order('z1')) # custom ordering
def无线电命令:
def字符排序顺序(a):
如果a.isnumeric():
返回ord('z')+1+int(a)
其他:
返回ord(a)
返回元组(映射(字符\排序\顺序,s))
打印('z1'<'zA'<'zA')#本机python排序
打印(无线电命令('zA')<无线电命令('zA')<无线电命令('z1'))#自定义命令
要改变
的行为并不容易,而且
可以使用几次,尽管代价可能很高。。。基本上,将字符串映射到将使用默认python比较运算符进行正确比较的值

import string

python_order = '0123456789' + string.ascii_uppercase
radio_order = string.ascii_uppercase + '0123456789'
to_py = string.maketrans(radio_order, python_order )
假设你可以从你链接的网站上阅读所有呼号范围,我会把它们放入一个列表
radio\u sign\u ranges
,然后翻译它们和你的有问题的呼号

signs = ['D6Z', 'D1Z', 'ZR1', 'ZRA']
signs_py = [ int(s.translate(to_py), 32) for s in signs ]
ranges_py =  [ int(s.translate(to_py), 32) for s in radio_sign_ranges ]
然后用一些数字工具找出哪个符号属于哪个国家。我想看看参数
x=signs\u py
和参数
bins=ranges\u py
,或者类似的东西

我是否可以将python的顺序从“…7<8<9
如果你想更深入地挖掘,也许可以看一看。

问题并没有提到排序。@ScottHunter不是排序,而是一般的排序:“但是python对数字和字符的排序方式与调用符号的排序方式是不同的”,所以创建一个为每个字符赋予权重的函数,然后运行一个“where sorted”(A,B,cmp=custom_cmp)“这类事情。等等,这太笨拙了,让我来研究一下first@RedM可能类似于
如果a在string.ascii_字母中,b在string.digits中:返回-1;如果a在string.digits中,b在string.ascii_字母中:返回1;返回a.\u cmp_uu(b)
您似乎不需要a-1排序。所有国家/地区都以Z结尾。许多国家/地区使用前2个字符进行完全解析,这可以存储在常规的dict中。AX=>澳大利亚。一些国家/地区的前2个字符的范围可以通过查找1个字符,然后进行简单的中间测试来解析(其中没有一项涉及比较NUM和ALPHA).Ex.char1 A=>美国,西班牙,char2 A-L=>美国,L-Z=>西班牙。C范围也是说明性的。C,然后是Y-Z=>加拿大。第二个字符范围中没有一个跨A-Z/0-9。ITU数据中专门的两步查找类可以做到这一点。第三个字符的作用示例如下:3DA-3DM斯威士兰(斐济王国)3DN-3DZ(共和国)但我只是在看的时候才发现的。对这个问题提出质疑的想法很好