Скажем, у меня есть два списка:
list1 = [3, 2, 4, 1, 1]
list2 = ['three', 'two', 'four', 'one', 'one2']
Если я запустлю list1.sort()
, он будет отсортирован, [1,1,2,3,4]
но есть ли способ list2
синхронизировать (так что я могу сказать, что элемент 4
принадлежит 'three'
)? Итак, ожидаемый результат будет:
list1 = [1, 1, 2, 3, 4]
list2 = ['one', 'one2', 'two', 'three', 'four']
Моя проблема в том, что у меня довольно сложная программа, которая отлично работает со списками, но мне нужно начать ссылаться на некоторые данные. Я знаю, что это идеальная ситуация для словарей, но я стараюсь избегать словарей в моей обработке, потому что мне нужно отсортировать значения ключей (если я должен использовать словари, я знаю, как их использовать).
В основном природа этой программы такова, что данные поступают в случайном порядке (как выше), мне нужно отсортировать их, обработать и затем отправить результаты (порядок не имеет значения, но пользователи должны знать, к какому результату относится какой ключ). Я думал о том, чтобы сначала поместить его в словарь, а затем отсортировать по списку, но у меня не было бы возможности дифференцировать элементы с одинаковыми значениями, если порядок не поддерживается (это может повлиять на передачу результатов пользователям). Поэтому в идеале, когда я получу списки, я бы предпочел найти способ сортировки обоих списков. Это возможно?
Ответы:
Один из классических подходов к этой проблеме - использовать идиому «декорировать, сортировать, декорировать», что особенно просто при использовании встроенной
zip
функции python :Это, конечно, больше не списки, но это легко исправить, если это важно:
Стоит отметить, что вышесказанное может пожертвовать скоростью ради краткости; версия на месте, которая занимает 3 строки, немного быстрее на моей машине для небольших списков:
С другой стороны, для больших списков однострочная версия может быть быстрее:
Как указывает Quantum7, предложение JSF все еще немного быстрее, но, вероятно, будет только немного быстрее, потому что Python использует один и тот же идиом DSU для всех видов ключей. Это происходит чуть ближе к голому металлу. (Это показывает, насколько хорошо оптимизированы
zip
процедуры!)Я думаю, что
zip
основанный на них подход более гибок и немного более читабелен, поэтому я предпочитаю его.источник
*
оператор выполняет распаковку аргументов ,zip(*x)
обладает интересным свойством обратного:l = [(1, 2), (3, 4)]; list(zip(*zip(*l))) == l
возвращаетTrue
. Это фактически оператор транспонирования.zip()
сам по себе является точно таким же оператором, но предполагает, что вы распаковали входную последовательность вручную.Вы можете сортировать индексы, используя значения в качестве ключей:
Чтобы получить отсортированные списки по заданным отсортированным индексам:
В вашем случае у вас не должно быть
list1
,list2
а достаточно одного списка пар:Это легко создать; в Python легко разобраться:
Сортировать только по первому значению:
источник
list()
вокруг ,map()
если вы хотите использовать этот код в Python 3.sorted_list1 = list(map(list1.__getitem__, indexes))
один мог сделатьsorted_list1 = [list1[i] for i in indexes]
.Я использовал ответ, данный senderle в течение долгого времени, пока я не обнаружил
np.argsort
. Вот как это работает.Я нахожу это решение более интуитивным, и оно работает очень хорошо. Исполнение:
Несмотря на то, что
np.argsort
он не самый быстрый, его легче использовать.источник
TypeError: only integer arrays with one element can be converted to an index
(Python 2.7.6, numpy 1.8.2). Чтобы это исправить, списки list1 и list2 должны быть объявлены как массивы numpy.np.argsort
не пытаться преобразоватьnp.array
внутренне.Преобразование Шварца . Встроенная сортировка Python стабильна, поэтому две
1
проблемы не вызывают проблем.источник
Что о:
источник
Вы можете использовать
zip()
иsort()
функцию для достижения этой цели :Надеюсь это поможет
источник
Вы можете использовать ключевой аргумент в методе sorted (), если у вас нет двух одинаковых значений в list2.
Код приведен ниже:
Он сортирует list2 в соответствии с соответствующими значениями в list1, но убедитесь, что при его использовании никакие два значения в list2 не считаются равными, поскольку функция list.index () дает первое значение
источник
Одним из способов является отслеживание того, куда идет каждый индекс, путем сортировки идентификаторов [0,1,2, .. n]
Это работает для любого количества списков.
Затем переместите каждый элемент на свою позицию. Использование сростков лучше всего.
Обратите внимание, что мы могли бы перебирать списки, даже не сортируя их:
источник
Если вы используете numpy, вы можете использовать,
np.argsort
чтобы получить отсортированные индексы и применить эти индексы к списку. Это работает для любого числа списка, который вы хотите отсортировать.источник
алгоритмическое решение:
Выходы:
->
Скорость выхода:0.2s
источник
Другой подход к сохранению порядка списка строк при сортировке по другому списку заключается в следующем:
вывод
источник
Я хотел бы расширить ответ open jfs , который отлично подошел для моей задачи: сортировка двух списков по третьему, оформленному списку :
Мы можем создать наш оформленный список любым способом, но в этом случае мы создадим его из элементов одного из двух исходных списков, которые мы хотим отсортировать:
Теперь мы можем применить решение JFS для сортировки наших двух списков по третьему
Изменить: Эй, ребята, я сделал блок пост об этом, проверьте, если вам это нравится :) 🐍🐍🐍
источник
источник