Python 如何恢复列表重排的模式
Python how to revert the pattern of a list rearrangement
所以我正在根据索引模式重新排列列表,并想找到一种方法来计算我需要将列表恢复为原始顺序的模式。
在我的示例中,我使用了一个包含 5 个项目的列表,因为我可以计算出将列表恢复到其原始状态所需的模式。
然而,当处理 100 个列表项时,这并不容易。
def rearrange(pattern: list, L: list):
new_list = []
for i in pattern:
new_list.append(L[i-1])
return new_list
print(rearrange([2,5,1,3,4], ['q','t','g','x','r']))
#['t', 'r', 'q', 'g', 'x']
并且为了把它设置回原来的模式
我会用
print(rearrange([3,1,4,5,2],['t', 'r', 'q', 'g', 'x']))
#['q', 't', 'g', 'x', 'r']
我要找的是一种计算模式“[3,1,4,5,2]”的方法
关于上面的例子。
吹口哨 运行 脚本,以便我可以将列表设置回其原始顺序。
使用更大的例子:
print(rearrange([18,20,10,11,13,1,9,12,16,6,15,5,3,7,17,2,19,8,14,4],['e','p','b','i','s','r','q','h','m','f','c','g','d','k','l','t','a','n','j','o']))
#['n', 'o', 'f', 'c', 'd', 'e', 'm', 'g', 't', 'r', 'l', 's', 'b', 'q', 'a', 'p', 'j', 'h', 'k', 'i']
但我需要知道用于此新列表的模式,以便 return 将其恢复到原始状态。
print(rearrange([???],['n', 'o', 'f', 'c', 'd', 'e', 'm', 'g', 't', 'r', 'l', 's', 'b', 'q', 'a', 'p', 'j', 'h', 'k', 'i']))
#['e','p','b','i','s','r','q','h','m','f','c','g','d','k','l','t','a','n','j','o']
这通常称为“argsort”。但是由于您使用的是基于 1 的索引,因此您 off-by-one。你可以用 numpy 得到它:
>>> pattern
[2, 5, 1, 3, 4]
>>> import numpy as np
>>> np.argsort(pattern) + 1
array([3, 1, 4, 5, 2])
没有 numpy:
>>> [1 + i for i in sorted(range(len(pattern)), key=pattern.__getitem__)]
[3, 1, 4, 5, 2]
像下面这样的东西呢:
def revert_pattern(pattern):
pattern_i = [0]*len(pattern)
for k in range(len(pattern)):
pattern_i[pattern[k]-1] = k+1
return pattern_i
print(revert_pattern([2, 5, 1, 3, 4]))
# [3, 1, 4, 5, 2]
注意:我遵循了您的逻辑,但我建议您使用 0 而不是 1 作为最小索引,因为它需要一些额外的 +1/-1 是可以避免的
def rearrange(p, l):
arr = [l[i - 1] for i in p]
d = {v : i + 1 for i, v in enumerate(arr)}
order = [d[k] for k in l]
return arr, order
a = [2, 5, 1, 3, 4]
b = ['q', 't', 'g', 'x', 'r']
rearrange(a, b)
# (['t', 'r', 'q', 'g', 'x'], [3, 1, 4, 5, 2])
或者也许
def revert(p):
z = zip(p, list(range(len(p))))
return [x + 1 for _, x in sorted(z)]
a = [2, 5, 1, 3, 4]
revert(a)
# [3, 1, 4, 5, 2]
所以我正在根据索引模式重新排列列表,并想找到一种方法来计算我需要将列表恢复为原始顺序的模式。
在我的示例中,我使用了一个包含 5 个项目的列表,因为我可以计算出将列表恢复到其原始状态所需的模式。
然而,当处理 100 个列表项时,这并不容易。
def rearrange(pattern: list, L: list):
new_list = []
for i in pattern:
new_list.append(L[i-1])
return new_list
print(rearrange([2,5,1,3,4], ['q','t','g','x','r']))
#['t', 'r', 'q', 'g', 'x']
并且为了把它设置回原来的模式 我会用
print(rearrange([3,1,4,5,2],['t', 'r', 'q', 'g', 'x']))
#['q', 't', 'g', 'x', 'r']
我要找的是一种计算模式“[3,1,4,5,2]”的方法 关于上面的例子。 吹口哨 运行 脚本,以便我可以将列表设置回其原始顺序。
使用更大的例子:
print(rearrange([18,20,10,11,13,1,9,12,16,6,15,5,3,7,17,2,19,8,14,4],['e','p','b','i','s','r','q','h','m','f','c','g','d','k','l','t','a','n','j','o']))
#['n', 'o', 'f', 'c', 'd', 'e', 'm', 'g', 't', 'r', 'l', 's', 'b', 'q', 'a', 'p', 'j', 'h', 'k', 'i']
但我需要知道用于此新列表的模式,以便 return 将其恢复到原始状态。
print(rearrange([???],['n', 'o', 'f', 'c', 'd', 'e', 'm', 'g', 't', 'r', 'l', 's', 'b', 'q', 'a', 'p', 'j', 'h', 'k', 'i']))
#['e','p','b','i','s','r','q','h','m','f','c','g','d','k','l','t','a','n','j','o']
这通常称为“argsort”。但是由于您使用的是基于 1 的索引,因此您 off-by-one。你可以用 numpy 得到它:
>>> pattern
[2, 5, 1, 3, 4]
>>> import numpy as np
>>> np.argsort(pattern) + 1
array([3, 1, 4, 5, 2])
没有 numpy:
>>> [1 + i for i in sorted(range(len(pattern)), key=pattern.__getitem__)]
[3, 1, 4, 5, 2]
像下面这样的东西呢:
def revert_pattern(pattern):
pattern_i = [0]*len(pattern)
for k in range(len(pattern)):
pattern_i[pattern[k]-1] = k+1
return pattern_i
print(revert_pattern([2, 5, 1, 3, 4]))
# [3, 1, 4, 5, 2]
注意:我遵循了您的逻辑,但我建议您使用 0 而不是 1 作为最小索引,因为它需要一些额外的 +1/-1 是可以避免的
def rearrange(p, l):
arr = [l[i - 1] for i in p]
d = {v : i + 1 for i, v in enumerate(arr)}
order = [d[k] for k in l]
return arr, order
a = [2, 5, 1, 3, 4]
b = ['q', 't', 'g', 'x', 'r']
rearrange(a, b)
# (['t', 'r', 'q', 'g', 'x'], [3, 1, 4, 5, 2])
或者也许
def revert(p):
z = zip(p, list(range(len(p))))
return [x + 1 for _, x in sorted(z)]
a = [2, 5, 1, 3, 4]
revert(a)
# [3, 1, 4, 5, 2]