Як я можу упорядкувати список? [зачинено]


107

Якщо у мене є список, [a,b,c,d,e]як я можу переупорядкувати елементи довільним чином [d,c,a,b,e]?

Редагувати: я не хочу їх перемішувати. Я хочу їх повторно замовити заздалегідь визначеним чином. (наприклад, я знаю, що 3-й елемент у старому списку повинен стати першим елементом у новому списку)


Можливо дубліката stackoverflow.com/questions/976882 / ...
kgiannakakis

4
Не вказуючи, як ви хочете замовити товари, важко відповісти. Ви хочете сортувати їх? Перемішати їх? Видалити деякі з них?
Мізіпзор

@tvanfosson: У цьому випадку довільне може також означати: взяти довільну (але чітко визначену) функцію сортування.
Фелікс Клінг

1
@mizipzor Я хочу їх повторно замовити заздалегідь визначеним способом. (Відредагував питання, щоб уточнити це)
Ніяз

@SilentGhost У ньому буде новий індекс. Може бути 4. Справа в тому, що я знаю новий порядок пунктів.
Ніяз

Відповіді:


226

Ви можете це зробити так

mylist = ['a', 'b', 'c', 'd', 'e']
myorder = [3, 2, 0, 1, 4]
mylist = [mylist[i] for i in myorder]
print(mylist)         # prints: ['d', 'c', 'a', 'b', 'e']

Це створює нову змінну. Як переупорядкувати список на місці? Спасибі
посоромляться

@Confounded Просто змініть заключний рядок на:mylist[:] = [mylist[i] for i in myorder]
Адам


11
>>> import random
>>> x = [1,2,3,4,5]
>>> random.shuffle(x)
>>> x
[5, 2, 4, 3, 1]

@ wenlibin02, тільки що запустив його під 2.7.5, і він все ще працює чудово. Ви отримуєте якусь помилку?
Марк

немає помилок, я просто набираю: 1) імпорт випадкових; x = [1, 2, 3]; random.shuffle (x); #it ​​повертає None; і 2) Я спробував np.random.shuffle. результати однакові.
Лібін Вень

Ой, вибачте! Я не усвідомлював, що безпосередньо змінюю значення x. Це не повернуло жодного. І це працює. Дякую.
Лібін Вень



2

Ви можете надати власну функцію сортування для list.sort():

Метод sort () бере необов'язкові аргументи для порівняння порівнянь.

  • CMP визначає для користувача функцію порівняння двох аргументів (елементів списку) , який повинен повертати негативне, нульове або позитивне число в залежності від того, чи вважається перший аргумент менше, дорівнює або більше другого аргументу: cmp=lambda x,y: cmp(x.lower(), y.lower()). Значенням за замовчуванням є None.

  • ключ визначає функцію одного аргументу , який використовується для вилучення ключа порівняння з кожного елемента списку: key=str.lower. Значенням за замовчуванням є None.

  • reverse - булева величина. Якщо встановлено значення True, то елементи списку сортуються так, ніби кожне порівняння було перетворене.

Взагалі процеси перетворення ключових і зворотних переходів набагато швидші, ніж визначення еквівалентної функції cmp. Це тому, що cmp викликається кілька разів для кожного елемента списку, тоді як клавіша та зворотний дотик кожного елемента лише один раз.


2
і як саме ви це реалізували?
SilentGhost

@SilentGhost: це розуміється як загальна відповідь. У випадку з ОП ваша відповідь є більш доречною. Проте я думаю, що важливо знати, що існує загальне рішення.
Фелікс Клінг

2

Якщо ви використовуєте numpy, існує акуратний спосіб зробити це:

items = np.array(["a","b","c","d"])
indices = np.arange(items.shape[0])
np.random.shuffle(indices)
print(indices)
print(items[indices])

Цей код повертає:

[1 3 2 0]
['b' 'd' 'c' 'a']

1
ОП шукає конкретного переупорядкування, а не загального переміщення.
Teepeemm

2

Якщо ви не так дбаєте про ефективність, ви можете розраховувати на індексацію масиву numpy, щоб зробити його елегантним:

a = ['123', 'abc', 456]
order = [2, 0, 1]
a2 = list( np.array(a, dtype=object)[order] )

1

З того, що я розумію у вашому питанні, виходить, що ви хочете застосувати перестановку, яку ви вказуєте на list. Це робиться шляхом вказівки іншого list(давайте називати його p), який містить покажчики елементів оригіналу, listякі повинні з'являтися в перестановці list. Потім ви використовуєте pдля створення нового list, просто замінюючи елемент у кожній позиції тим, чий індекс знаходиться в цій позиції в p.

def apply_permutation(lst, p):
    return [lst[x] for x in p]

arr=list("abcde")
new_order=[3,2,0,1,4]

print apply_permutation(arr,new_order)

Це відбитки ['d', 'c', 'a', 'b', 'e'].

Це фактично створює нове list, але його можна тривіально модифікувати для перестановки оригіналу "на місці".


1

Ще однією річчю, яку можна вважати, є інша інтерпретація, на яку вказує безтьма

Код в Python 2.7

В основному:

  1. Упорядкування за значенням - вже вирішено AJ вище
  2. Впорядкувати за індексом

    mylist = ['a', 'b', 'c', 'd', 'e']
    myorder = [3, 2, 0, 1, 4]
    
    mylist = sorted(zip(mylist, myorder), key=lambda x: x[1])
    print [item[0] for item in mylist]

Це надрукує ['c', 'd', 'b', 'a', 'e']



-1

Це те, що я використовував, коли натрапляв на цю проблему.

def order(list_item, i): # reorder at index i
    order_at = list_item.index(i)
    ordered_list = list_item[order_at:] + list_item[:order_at]
    return ordered_list

EX: для малих літер

order(string.ascii_lowercase, 'h'):
>>> 'hijklmnopqrstuvwxyzabcdefg'

Він просто зміщує список на вказаний індекс

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.