我有一种感觉,这个问题的核心概念可能是一个重复的问题,但我找不到。
我有一堆无线电呼号,想找出here的原产国。
我尝试过做一些基本的比较来查找国家/地区的位置,但是Python对数字和字符的排序方式与呼号的排序方式是不同的:
在Python "ZR1" < "ZRA" == True
中,但在呼号约定中应该是False
。
有没有办法将Python的顺序从... 7 < 8 < 9 < A < B …
更改为... X < Y < Z < 0 < 1 < 2 …
发布于 2016-07-04 23:47:00
您可以创建一个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
发布于 2016-07-04 23:19:03
像sorted()
这样的函数允许您提供自己的cmp
函数-您只需实现它。但你可以自由地说,数字超过了字母,通常的排序算法会处理剩下的部分。
如果你只是想比较而不是排序,你必须为它实现你自己的函数。从两个字符串中逐个字符,并在此基础上做出决定。
发布于 2016-07-04 23:54:07
您可以简单地编写自己的键函数,如下所示:
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),然后将我们的字符串映射到这些int
s的tuple
s。很容易看出,int
s的结果tuple
s将以我们需要比较原始字符串的方式进行比较。
https://stackoverflow.com/questions/38187938
复制相似问题