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

时间:2016-07-04 15:15:58

标签: python sorting

我觉得这个核心概念可能是一个重复的问题,但我无法找到它。

我有一堆无线电呼号,想要从here找到原籍国。

我尝试进行基本比较以查找国家/地区位置,但Python命令数字和字符与调用标记方式的方式不同:

在Python "ZR1" < "ZRA" == True中,但在callign约定中这将是False

无论如何,我可以将Python的排序从... 7 < 8 < 9 < A < B …更改为... X < Y < Z < 0 < 1 < 2 …吗?

4 个答案:

答案 0 :(得分:1)

sorted()这样的功能允许您提供自己的cmp功能 - 您只需要实现它。但是你可以自由地说数字超过了字母,通常的排序算法会处理其余的数据。

如果你只想比较事物而不是排序,你必须为它实现自己的功能。从两个字符串逐个字符去做,然后根据它做出决定。

答案 1 :(得分:1)

你可以在&#34;正确&#34;中创建一个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

答案 2 :(得分:0)

您可以简单地编写自己的密钥功能,如下所示:

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 s),然后将字符串映射到tuple的{​​{1}}个。很容易看出,int的{​​{1}} s tuple s将以我们需要比较原始字符串的方式进行比较。

答案 3 :(得分:0)

你可以使用string.translate几次,虽然它可能代价很高......基本上,将字符串映射到一个值,使用默认的python比较运算符进行正确比较。

import string

python_order = '0123456789' + string.ascii_uppercase
radio_order = string.ascii_uppercase + '0123456789'
to_py = string.maketrans(radio_order, python_order )

假设您可以阅读您链接到的网站上的所有通话标记范围,我会将它们放入列表radio_sign_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 ]

然后使用一些数字工具来查找哪个标志属于哪个国家/地区。我会看看numpy.digitize其中参数x=signs_py和参数bins=ranges_py,或类似的东西......

  

无论如何,我可以从&#34; ... 7&lt;&lt; 8&lt; 9&lt; A&lt; B ......&#34;到&#34; ...... X&lt; Y&lt; Z&lt; 0&lt; 1&lt; 2 ...&#34;?

如果你想深入挖掘,也许可以看看here