Jak mogę zmienić kolejność listy? [Zamknięte]

108

Jeśli mam listę, [a,b,c,d,e]jak mogę zmienić kolejność pozycji w dowolny sposób [d,c,a,b,e]?

Edycja: nie chcę ich tasować. Chcę je ponownie zamówić we wstępnie zdefiniowany sposób. (na przykład wiem, że 3. element starej listy powinien stać się pierwszym elementem nowej listy)

Niyaz
źródło
Prawdopodobnie duplikat stackoverflow.com/questions/976882/…
kgiannakakis
4
Bez określenia, w jaki sposób chcesz zamówić produkty, trudno jest odpowiedzieć. Chcesz je posortować? Potasować je? Usunąć niektóre z nich?
Mizipzor
@tvanfosson: W tym przypadku arbitralne może również oznaczać: wybierz dowolną (ale dobrze zdefiniowaną) funkcję sortowania.
Felix Kling
1
@mizipzor Chcę je ponownie zamówić w predefiniowany sposób. (Zredagował pytanie, aby to wyjaśnić)
Niyaz
@SilentGhost Będzie miał nowy indeks. Może 4. Chodzi o to, że znam nową kolejność przedmiotów.
Niyaz

Odpowiedzi:

226

Możesz to zrobić w ten sposób

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.
źródło
1
Tworzy to nową zmienną. Jak zmienić kolejność listy na miejscu? Dzięki
zdezorientowany
@Confounded Po prostu zmień ostatnią linię na:mylist[:] = [mylist[i] for i in myorder]
Adam
13
>>> a = [1, 2, 3]
>>> a[0], a[2] = a[2], a[0]
>>> a
[3, 2, 1]
SilentGhost
źródło
1
Po prostu nie mogłem zrozumieć składni, dopóki nie zdałem sobie sprawy, że jest to jednoczesne przypisanie parami . ":-)
loved.by.Jesus
11
>>> import random
>>> x = [1,2,3,4,5]
>>> random.shuffle(x)
>>> x
[5, 2, 4, 3, 1]
znak
źródło
@ wenlibin02, po prostu uruchomiłem go pod 2.7.5 i nadal działa dobrze. Czy pojawia się jakiś błąd?
Mark
bez błędu, po prostu wpisuję: 1) importuj losowo; x = [1, 2, 3]; random.shuffle (x); #it ​​zwraca None; i 2) próbowałem np.random.shuffle. wyniki są takie same.
Libin Wen,
Przepraszam! Nie zdawałem sobie sprawy, że bezpośrednio zmieniam wartość x. To nie zwróciło Żaden. I to działa. Dzięki.
Libin Wen
6

Czy ostateczna kolejność jest określona przez listę indeksów?

>>> 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']

edytuj: meh. AJ był szybszy ... Jak mogę zmienić kolejność listy w Pythonie?

Raphaël Saint-Pierre
źródło
3
>>> a=["a","b","c","d","e"]
>>> a[0],a[3] = a[3],a[0]
>>> a
['d', 'b', 'c', 'a', 'e']
ghostdog74
źródło
2

Możesz udostępnić własną funkcję sortowania, aby list.sort():

Metoda sort () przyjmuje opcjonalne argumenty do kontrolowania porównań.

  • CMP określa funkcję porównawczą zwyczaj dwa argumenty (elementy listy), które powinien zwrócić ujemny, zerowy lub dodatnią liczbę w zależności od tego, czy pierwszy argument jest mniejszy, równy lub większy niż drugi argument: cmp=lambda x,y: cmp(x.lower(), y.lower()). Wartość domyślna to None.

  • Kluczowe Określa funkcję jednego argumentu, który jest używany, aby wyodrębnić klucza porównania z każdego elementu listy: key=str.lower. Wartość domyślna to None.

  • reverse jest wartością logiczną. Jeśli jest ustawiona na True, elementy listy są sortowane tak, jakby każde porównanie zostało odwrócone.

Ogólnie rzecz biorąc, klucz i procesy konwersji odwrotnej są znacznie szybsze niż określanie równoważnej funkcji cmp. Dzieje się tak, ponieważ cmp jest wywoływane wiele razy dla każdego elementu listy, podczas gdy klawisz i reverse dotykają każdego elementu tylko raz.

Felix Kling
źródło
2
i jak dokładnie byś to zaimplementował?
SilentGhost
@SilentGhost: To ma być ogólna odpowiedź. W przypadku PO twoja odpowiedź jest bardziej odpowiednia. Niemniej jednak uważam, że ważne jest, aby wiedzieć, że istnieje ogólne rozwiązanie.
Felix Kling
2

Jeśli używasz numpy, jest na to zgrabny sposób:

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

Ten kod zwraca:

[1 3 2 0]
['b' 'd' 'c' 'a']
user2228129
źródło
1
OP szuka konkretnej zmiany kolejności, a nie ogólnego tasowania.
Teepeemm
2

Jeśli nie zależy Ci tak bardzo na wydajności, możesz polegać na indeksowaniu tablic numpy, aby uczynić go eleganckim:

a = ['123', 'abc', 456]
order = [2, 0, 1]
a2 = list( np.array(a, dtype=object)[order] )
Shaohua Li
źródło
1

Z tego, co rozumiem z Twojego pytania, wynika, że ​​chcesz zastosować permutację określoną w pliku list. Odbywa się to poprzez określenie innego list(nazwijmy to p), który przechowuje indeksy elementów oryginału, listktóre powinny pojawić się w permutacji list. Następnie ptworzysz nowy list, po prostu zastępując element w każdej pozycji tym, którego indeks znajduje się na tej pozycji 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)

To drukuje ['d', 'c', 'a', 'b', 'e'].

To faktycznie tworzy nowy list, ale można go w trywialny sposób zmodyfikować, aby zastąpić oryginał „na miejscu”.

MAK
źródło
1

Jeszcze jedną rzeczą, którą można wziąć pod uwagę, jest inna interpretacja, na którą wskazuje Darkless

Kod w Pythonie 2.7

Głównie:

  1. Uporządkuj według wartości - już rozwiązane przez AJ powyżej
  2. Uporządkuj według indeksu

    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]

Spowoduje to wydrukowanie ['c', 'd', 'b', 'a', 'e']

Kshitij Satpute
źródło
0
newList = [oldList[3]]
newList.extend(oldList[:3])
newList.extend(oldList[4:])
inspectorG4dget
źródło
-1

Właśnie tego użyłem, kiedy natknąłem się na ten problem.

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: dla małych liter

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

Po prostu przesuwa listę do określonego indeksu

AA Ron
źródło