Entonces, estoy reorganizando una lista basada en un patrón de índice y me gustaría encontrar una manera de calcular el patrón que necesito para revertir la lista a su orden original.
para mi ejemplo, estoy usando una lista de 5 elementos, ya que puedo calcular el patrón necesario para revertir la lista a su estado original.
Sin embargo, esto no es tan fácil cuando se trata de 100 elementos de la lista.
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']y para volver a establecerlo en el patrón original, usaría
print(rearrange([3,1,4,5,2],['t', 'r', 'q', 'g', 'x'])) #['q', 't', 'g', 'x', 'r']Lo que estoy buscando es una forma de calcular el patrón "[3,1,4,5,2]" con respecto al ejemplo anterior. mientras ejecuta el script para que pueda restablecer la lista a su orden original.
Usando un ejemplo más grande:
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']pero necesito saber el patrón a usar con esta nueva lista para devolverla a su estado original.
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']Esto se llama comúnmente "argsort". Pero dado que está utilizando la indexación basada en 1, está fuera de lugar. Puedes obtenerlo con numpy:
>>> pattern [2, 5, 1, 3, 4] >>> import numpy as np >>> np.argsort(pattern) + 1 array([3, 1, 4, 5, 2])Sin numpy:
>>> [1 + i for i in sorted(range(len(pattern)), key=pattern.__getitem__)] [3, 1, 4, 5, 2]¿Qué pasa con algo como a continuación:
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]Nota: seguí su lógica, pero le recomiendo que use 0 como los índices más pequeños en lugar de 1, ya que requiere algunos +1/-1 adicionales que podrían evitarse
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])O tal vez
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]