Как я могу решить эту ошибку, которая возникает, когда я пытаюсь отсортировать вложенный список на основе другого вложенного? - PullRequest
1 голос
/ 12 апреля 2020

Я пытался основывать свои решения на других вопросах, заданных здесь, но они не совсем работают.

У меня есть вложенный список:

s = [[[921, 640], [4007, 49], [4821, 40]],
     [[1270, 20], [1943, 393], [4821, 183]],
     [[1300, 95], [857, 641], [4821, 83]]]

Я хочу отсортировать значения по индексу 0 во вложенном на основе значений другого вложенного списка. Другой список выглядит следующим образом:

i = [[921, 4281, 4007], [1943, 1270, 4821], [4821, 1300, 857]]

Как видно, значения подсписков в i совпадают со значениями по индексу 0 в подсписках s, но они не того же порядка. Теперь я хочу упорядочить значения в s на основе значений в i следующим образом:

s_new = [[[921, 640],[4821, 40], [4007, 49]],
        [[1943, 393],[1270, 20], [4821, 183]],
        [[4821, 83],[1300, 95], [857, 641]]]

Я пробовал этот код на основе других вопросов с похожими ответами:

s_new = [(sorted(x, key=lambda item: i.index(item[0]))) for x in s]

Но я получаю ошибку:

ValueError: 921 is not in list

Что я делаю неправильно и почему я получаю эту ошибку?

Я задавал этот вопрос вчера, но он был помечен как дубликат. Однако связанные вопросы и ответы не могли решить мою проблему.

1 Ответ

3 голосов
/ 12 апреля 2020

Вам не хватает вложенного уровня, вы можете сделать это:

s = [[[921, 640], [4007, 49], [4821, 40]],
     [[1270, 20], [1943, 393], [4821, 183]],
     [[1300, 95], [857, 641], [4821, 83]]]

i = [[921, 4821, 4007], [1943, 1270, 4821], [4821, 1300, 857]]

s_new = [(sorted(x, key=lambda item: i[j].index(item[0]))) for j, x in enumerate(s)]

for x in s_new:
    print(x) 

Выход

[[921, 640], [4821, 40], [4007, 49]]
[[1943, 393], [1270, 20], [4821, 183]]
[[4821, 83], [1300, 95], [857, 641]]

Также обратите внимание, что i из вашего примера 4821 вместо 4281. В качестве альтернативы вы можете выполнить итерацию параллельно по двум спискам, используя zip:

s_new = [sorted(si, key=lambda x: ij.index(x[0])) for si, ij in zip(s, i)]

Из-за вызова индекса два вышеуказанных подхода O(n*n), для более длинного списка лучше использовать словарь поиска, для пример:

def sort(ls, order):
    priority = {k: p for p, k in enumerate(order)}
    return sorted(ls, key=lambda x: priority[x[0]])


s_new = [sort(si, ij) for si, ij in zip(s, i)]

Использование словаря дает O(n log n) стоимость стандартного алгоритма сортировки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...