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

2024-05-17 07:15:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我觉得这个问题的核心可能是一个重复的问题,但我找不到。你知道吗

我有一堆无线电呼号,想从here找到原产国。你知道吗

我试着做一些基本的比较来找出国家的位置,但是Python对数字和字符的排序方式与呼号的排序方式是不同的:

在Python中"ZR1" < "ZRA" == True,但这将是调用符号约定中的False。你知道吗

我是否可以将Python的顺序从... 7 < 8 < 9 < A < B …更改为... X < Y < Z < 0 < 1 < 2 …?你知道吗


Tags: falsetrue核心here排序顺序方式符号
3条回答

sorted()这样的函数允许您提供自己的cmp函数—您只需实现它。但你可以自由地说,数字是在字母之上的,通常的排序算法会处理剩下的部分。你知道吗

如果您只想比较事物而不是排序,那么就必须实现自己的函数。从两个字符串中逐个字符地进行操作,并在此基础上做出决定。你知道吗

您只需编写自己的键函数,如下所示:

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

改变><符号的行为并不容易,但我认为这种方法解决了您的问题。如果要根据这个新顺序对一些字符串进行排序,还可以使用radio_order作为key参数。你知道吗

在本例中,我们可以保留python的approach来比较序列(字符串),但希望改变这些序列(字符)的部分比较方式。因此,我们将字符映射到以我们喜欢的方式进行比较的内容(int),然后将字符串映射到这些int中的tuple中的int中的tuple中的int将以我们需要比较原始字符串的方式进行比较。你知道吗

您可以创建一个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']

要使此比较自动化,还可以创建class Callsign并相应地重写__cmp____eq____lt__方法:

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

相关问题 更多 >