首页 > 解决方案 > 按键对列表进行排序,然后以与第一个相同的方式对另一个列表进行排序?

问题描述

例如有三个列表:

unsorted_key = ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p']
sorted_key = ['e', 'i', 'o', 'p', 'q', 'r', 't', 'u', 'w', 'y']
ciphertext = [
              ['u', 't', 'x', 'e'],
              ['p', 'r', 'k', 'p'],
              ['v', 'n', 'x', 'a'],
              ['n', 'h', 'e', 'x'],
              ['x', 'h', 'm', 's'],
              ['l', 'x', 'c', 'x'],
              ['x', 'c', 'y', 'a'],
              ['t', 'u', 'o', 'x'],
              ['e', 'r', 'm', 'e'],
              ['y', 'y', 'e', 'x']
             ]

是否可以按照sorted_key的顺序排序到unsorted_key中,再按照密文的顺序排序呢?

当将“q”从 sorted_key[4] 移动到 sorted_key[0] 时,它应该将 ciphertext[4] 移动到 ciphertext[0]。

我一直在考虑它,我能想到的唯一方法是使用辅助函数从 unsorted_key 的顺序动态生成并返回一个 lambda 函数,然后使用类似的东西:

sorted_key, ciphertext = (list(i) for i in zip(*sorted(zip(sorted_key, ciphertext), key=generate(unsorted_key))))

但我真的不知道 zip() 或 lambda 函数是如何工作的,也不知道如何将自定义排序顺序合二为一,或者是否甚至可以返回一个以在 sorted() 中使用。我真的无法解决这个问题,所以任何帮助将不胜感激!

标签: pythonpython-3.xsorting

解决方案


我不确定我是否明白这一点,但是...

首先确定动作(可以相反,我不清楚):

moves = [ [i, sorted_key.index(c)] for i, c in enumerate(unsorted_key) ]
#=> [[0, 4], [1, 8], [2, 0], [3, 5], [4, 6], [5, 9], [6, 7], [7, 1], [8, 2], [9, 3]]

也许在[i, sorted_key.index(c)].

将移动应用到接收器 ( res):

res = [ None for _ in range(len(ciphertext))]
for a, b in moves:
  res[a] = ciphertext[b]

所以输出应该是:

for line in res:
  print(line)

# ['x', 'h', 'm', 's']
# ['e', 'r', 'm', 'e']
# ['u', 't', 'x', 'e']
# ['l', 'x', 'c', 'x']
# ['x', 'c', 'y', 'a']
# ['y', 'y', 'e', 'x']
# ['t', 'u', 'o', 'x']
# ['p', 'r', 'k', 'p']
# ['v', 'n', 'x', 'a']
# ['n', 'h', 'e', 'x']


用于测试执行时间

import timeit, functools

def custom_sort(ciphertext, sorted_key, unsorted_key):
  return [ ciphertext[b] for _, b in [ [i, sorted_key.index(c)] for i, c in enumerate(unsorted_key) ] ]


custom_sort = timeit.Timer(functools.partial(custom_sort, ciphertext, sorted_key, unsorted_key))

print(custom_sort.timeit(20000))

推荐阅读