我试图弄清楚如何在Python3.5中为二维数组编写自定义排序函数。这样做的目的是将数组转换为半行梯级形式,其中任何带前导1的行都移动到其他行的顶部,任何带前导0的行都移动到底部,其余的行则在中间排序。您可以看到下面的示例矩阵。
before = [
[5, 3, 1, 2, 3, 1],
[0, 1, -1, 2, -3, 4],
[0, 0, 2, 2, -1, 3],
[1, 2, 5, -2, 4, -3],
[2, 1, 1, -1, 4, 2],
[0, 0, 1, 4, 5, -1]
]
after = [
[1, 2, 5, -2, 4, -3],
[2, 1, 1, -1, 4, 2],
[5, 3, 1, 2, 3, 1],
[0, 1, -1, 2, -3, 4],
[0, 0, 1, 4, 5, -1],
[0, 0, 2, 2, -1, 3]
]如果我是用Java实现这一点的话,我会编写一个比较器对象或一个compareTo方法。但是从网络上看,在pythonic中,它似乎不再是在排序时使用3+参数的pythonic方法。
现在我可以用
for i in range(len(mat)-1, -1, -1):
mat.sort(key=itemgetter(i), reverse=True)要做到这一点,但是这不会将第一个非零值为1的行移到顶部。
我很感激任何建议,任何人都可能不得不这样做,以最仿生的方式。而且,如果有人有任何好的资源来学习正确的节奏曲方式来做其他事情,我会很感激的。有时,我会像用其他语言写东西一样做一些事情,却没有意识到Python有一种首选的方法(我正在看您,列表理解)。
发布于 2017-11-20 07:48:40
你可以尝试这样的方法:
mat.sort(key=lambda l: [
(0, 0) if x == 1 else
(2, 0) if x == 0 else
(1, x) for x in l
])并利用元组和列表按词典顺序比较的事实,比较前两个元素,等等。
编辑:
我改变了我的观点,我认为与创建一个比较函数(这个函数并不是那么清晰)相比,像上面所示的那样做可能是更好的方法,而且更快。
测试代码:
TRIALS = 10000
mat = [
[5, 3, 1, 2, 3, 1],
[0, 1, -1, 2, -3, 4],
[0, 0, 2, 2, -1, 3],
[1, 2, 5, -2, 4, -3],
[2, 1, 1, -1, 4, 2],
[0, 0, 1, 4, 5, -1]
]
@functools.cmp_to_key
def matcmp(a, b):
for ai, bi in zip(a, b):
if (ai == bi): continue
if (0 != ai != 1 and 0 != bi != 1):
return a < b
elif (ai == 1 or bi == 0):
return -1
else:
return 1
else:
return 0
start = time.time()
for i in range(TRIALS):
sorted(mat, key=matcmp)
print(time.time() - start)
start = time.time()
for i in range(TRIALS):
sorted(mat, key=lambda l: [
(0, 0) if x == 1 else
(2, 0) if x == 0 else
(1, x) for x in l
])
print(time.time() - start)输出:
0.10232377052307129
0.09116077423095703https://stackoverflow.com/questions/47386541
复制相似问题