Python 比较字符串和数字,解码无线电呼号
我有一种感觉,这个问题的核心概念可能是一个重复的问题,但我找不到它 我有一大堆无线电呼号,想找到它的原产国 我尝试进行基本的比较以找到国家/地区,但Python对数字和字符的排序方式与呼号的排序方式不同: 在Python中,在呼号约定中,这将是Python 比较字符串和数字,解码无线电呼号,python,sorting,Python,Sorting,我有一种感觉,这个问题的核心概念可能是一个重复的问题,但我找不到它 我有一大堆无线电呼号,想找到它的原产国 我尝试进行基本的比较以找到国家/地区,但Python对数字和字符的排序方式与呼号的排序方式不同: 在Python中,在呼号约定中,这将是False 我可以从更改Python的顺序吗。。。7
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(共和国)但我只是在看的时候才发现的。对这个问题提出质疑的想法很好