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)



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

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


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

@ 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


3
>>> a=["a","b","c","d","e"]
>>> a[0],a[3] = a[3],a[0]
>>> a
['d', 'b', 'c', 'a', 'e']

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.


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

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

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”.


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



-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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.