2015-10-06 17 views
6

Próbuję obrócić listę o 90 stopni. Na przykład to zmienić:indeks listy poza zakresem, ilekroć zmieniam rozmiar listy

[[1,2,3], [4,5,6], [7,8,9]] 

do

[[7,4,1], [8,5,2],[9,6,3]] 

wizualnie:

[[1,2,3],   [[7,4,1], 
[4,5,6], -->  [8,5,2], 
[7,8,9]]   [9,6,3]] 

Ilekroć zmienić rozmiar listy, aby mieć więcej elementów lub mniej to zawsze mówi, że indeks jest z zasięg? Co się dzieje?

def rotate(list1): 
    bigList = [] #create a list that we will append on to 
    for i in (range(len(list1)+1)): #loop through the list looking at the indexes 
     newList = [] 
     for j in reversed(range(len(list1))): #reverse that list 
      newList.append(list1[j][i]) 
     bigList.append((newList)) #append the elements to the bigList reversed 
    return bigList 
+0

Czy Twój wcięcie pisał tu prawidłowa? –

+0

@AnandSKumar Nie sądzę, że jest, a także jego lista nie jest właściwa. – Leb

+0

@AnandSKumar Powinno być teraz poprawne, przykro mi, że wciąż przyzwyczaja się do bloków kodu podczas wpisywania go w –

Odpowiedz

4

Co robisz można bardzo łatwo zrobić w jednej linii z wykorzystaniem reversed i zip. Rzeczywisty problem w kodzie podanym poniżej w tej odpowiedzi.

Przykład -

list(zip(*reversed(yourlist))) 

Nie trzeba się list(...) dla Pythonie 2.x, jak zip() zwraca listę w Pythonie 2.x.

Demo -

>>> list(zip(*reversed([[1,2,3], [4,5,6], [7,8,9]]))) 
[(7, 4, 1), (8, 5, 2), (9, 6, 3)] 
>>> list(zip(*reversed([[1,2,3,4], [5,6,7,8], [9,10,11,12]]))) 
[(9, 5, 1), (10, 6, 2), (11, 7, 3), (12, 8, 4)] 

Jeśli chcesz wykaz list, zamiast listy krotki, można użyć listowych (lub map(list, zip(*reversed(....)))). Przykład -

[list(x) for x in zip(*reversed(yourlist))] 

Demo -

>>> [list(x) for x in zip(*reversed([[1,2,3], [4,5,6], [7,8,9]]))] 
[[7, 4, 1], [8, 5, 2], [9, 6, 3]] 
>>> [list(x) for x in zip(*reversed([[1,2,3,4], [5,6,7,8], [9,10,11,12]]))] 
[[9, 5, 1], [10, 6, 2], [11, 7, 3], [12, 8, 4]] 

* jest składnia rozpakowaniu więc lista zwrócony przez reversed() rozpakowaniu na zip() i przepuszcza odsunięte do niego.

Następnie funkcja zip() łączy w sobie elementy każdego z jej argumentów na odpowiadającym mu indeksie (jak wszystkie pierwsze argumenty razem, wszystkie drugie argumenty razem itp.), Stąd otrzymujemy wynik, którego potrzebujemy.


Rzeczywisty problem dla oryginalnego kodu wystąpił z powodu następujących linii -

for i in (range(len(list1)+1)): 

jesteś zapętlenie aż len(list1) + 1, stąd ostatecznie próby uzyskania dostępu do elementów jak list1[0][len(list1)], ale że nie istnieje w Twój przypadek.

Zakładając, że podlista list1 będzie zawierała taką samą ilość elementów, to, czego naprawdę potrzebujesz, będzie len(list1[0]).Przykład -

def rotate(list1): 
    bigList = [] #create a list that we will append on to 
    for i in (range(len(list1[0]))): #loop through the list looking at the indexes 
     newList = [] 
     for j in reversed(range(len(list1))): #reverse that list 
      newList.append(list1[j][i]) 
     bigList.append((newList)) #append the elements to the bigList reversed 
    return bigList 

Demo -

>>> def rotate(list1): 
...  bigList = [] #create a list that we will append on to 
...  for i in (range(len(list1[0]))): #loop through the list looking at the indexes 
...   newList = [] 
...   for j in reversed(range(len(list1))): #reverse that list 
...    newList.append(list1[j][i]) 
...   bigList.append((newList)) #append the elements to the bigList reversed 
...  return bigList 
... 
>>> rotate([[1,2,3], [4,5,6], [7,8,9]]) 
[[7, 4, 1], [8, 5, 2], [9, 6, 3]] 
>>> rotate([[1,2,3,4], [5,6,7,8], [9,10,11,12]]) 
[[9, 5, 1], [10, 6, 2], [11, 7, 3], [12, 8, 4]] 

+1

Czy mógłbyś wyjaśnić, co się dzieje na liście 'list (zip (* odwrócony (...))) i co to znaczy' * '? –

+1

'*' jest składnią rozpakowywania, więc lista zwrócona przez 'reverse()' jest rozpakowywana do 'zip()' i przekazywana jako oddzielne argumenty. Następnie funkcja 'zip()' łączy elementy każdego z argumentów na odpowiadającym jej indeksie (jak wszystkie pierwsze argumenty razem, wszystkie drugie argumenty razem itp.), Stąd otrzymujemy wynik, którego potrzebujemy. Zaktualizowano to w odpowiedzi. –

1

Zmień

for i in (range(len(list1)+1)) 

do

for i in (range(len(list1))) 

i powinno działać

+0

to nie działa, jeśli mam więcej elementów na liście, na przykład zawiesza się w [[1,2,3,4], [5,6,7,8], [9,10,11, 12]] –

0

Jeśli zmienić linię do for i:

for i in (range(len(list1))): 

następnie daje oczekiwanego rezultatu.

pamiętać, że kod działa tylko na listach n-by-n, a nie dla list n-by-m

typowym przykładem off by one error ;-)

Powiązane problemy