Как я могу изменить порядок списка? [закрыто]

108

Если у меня есть список, [a,b,c,d,e]как я могу изменить порядок элементов произвольным образом, например [d,c,a,b,e]?

Изменить: я не хочу их перемешивать. Я хочу переупорядочить их заранее определенным образом. (например, я знаю, что 3-й элемент в старом списке должен стать первым элементом в новом списке)

Нияз
источник
Вероятно, дубликат stackoverflow.com/questions/976882/…
kgiannakakis 01
4
Трудно ответить, не указав, как вы хотите расположить предметы. Вы хотите их отсортировать? Перетасовать их? Удалить некоторые из них?
Mizipzor 01
@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']
AJ.
источник
1
Это создает новую переменную. Как изменить порядок списка на месте? Спасибо
постыдятся
@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) import random; х = [1, 2, 3]; random.shuffle (х); #it ​​не возвращает None; и 2) Я пробовал np.random.shuffle. результаты такие же.
Либин Вэнь,
Ой, извини! Я не осознавал, что напрямую меняю значение x. Он действительно не вернул None. И это работает. Спасибо.
Libin Wen
6

Окончательный порядок определяется списком индексов?

>>> items = [1, None, "chicken", int]
>>> order = [3, 0, 1, 2]

>>> ordered_list = [items[i] for i in order]
>>> ordered_list
[<type 'int'>, 1, None, 'chicken']

редактировать: мех. AJ был быстрее ... Как я могу изменить порядок списка в Python?

Рафаэль Сен-Пьер
источник
3
>>> a=["a","b","c","d","e"]
>>> a[0],a[3] = a[3],a[0]
>>> a
['d', 'b', 'c', 'a', 'e']
призрачная собака74
источник
2

Вы можете предоставить свою собственную функцию сортировки, чтобы list.sort():

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

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

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

  • reverse - это логическое значение. Если установлено значение True, то элементы списка сортируются, как если бы каждое сравнение было обратным.

В общем, процессы ключевого и обратного преобразования намного быстрее, чем указание эквивалентной функции cmp. Это связано с тем, что cmp вызывается несколько раз для каждого элемента списка, в то время как клавиши key и reverse касаются каждого элемента только один раз.

Феликс Клинг
источник
2
и как именно вы это реализуете?
SilentGhost 01
@SilentGhost: это общий ответ. В случае с OP ваш ответ более уместен. Тем не менее, я думаю, важно знать, что существует универсальное решение.
Феликс Клинг,
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']
user2228129
источник
1
OP ищет конкретную перестановку, а не общую перетасовку.
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, но его можно тривиально изменить, чтобы переставить оригинал «на место».

MAK
источник
1

Еще одна вещь, которую можно принять во внимание, - это другая интерпретация, указанная darkless

Код на 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']

Кшитидж Сатпуте
источник
0
newList = [oldList[3]]
newList.extend(oldList[:3])
newList.extend(oldList[4:])
инспекторG4dget
источник
-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'

Он просто перемещает список по указанному индексу

А.А. Рон
источник