2015-10-06 8 views
6

リストのリストを90度回転しようとしています。リストのインデックスが範囲外になるとリストのサイズが変更されるたびに

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

視覚

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

へ:たとえば、この変更私はより多くの要素以下であることが、リストのサイズを変更するたび

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

をそれは常にインデックスが外にあると言います範囲?何が起こっている?

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

典型的な例は、ここに正しいに投稿されたあなたのインデントですか?のn行nのリストのために働くといないことを

注意 –

+0

@AnandSKumar私はそうは思わないし、彼のリストも正しくない。 – Leb

+0

@AnandSKumar今は正しいはずですが、入力中にコードブロックに慣れてしまって申し訳ありません –

答えて

4

を動作するはずです非常に簡単にreversedzipを使用して、単一のラインで行うことができます。この回答の下であなたのコードの実際の問題。

例 - zip()のPython 2.xのにリストを返すよう

list(zip(*reversed(yourlist))) 

あなたは、list(...)Python用2.xのは必要ありません。

デモ -

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

あなたの代わりにタプルのリストのリストのリストを、必要な場合は、リストの内包(またはmap(list, zip(*reversed(....))))を使用することができます。例 -

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

デモ -

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

*開梱するための構文ですので、reversed()によって返されたリストは、zip()に展開し、それとは別の引数として渡されます。

次に、zip()関数は、それぞれの引数の要素を対応するインデックス(すべての最初の引数、すべての2番目の引数など)で結合します。したがって、必要な結果が得られます。元のコードの実際の問題は、次の行で発生した


-

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

あなたは最終的にあなたがlist1[0][len(list1)]ような要素にアクセスしようとするが、それは存在しないため、len(list1) + 1までループしていますあなたの場合。

list1のサブリストはすべて同じ量の要素を持つと仮定すると、本当に必要なものはlen(list1[0])となります。例 -

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 

デモ -

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

'list(zip(* reversed(...))')行に何が起こっているのかを説明してください。 '*'はどういう意味ですか? –

+1

'*'はアンパックの構文です。したがって、 'reversed()'によって返されたリストは 'zip()'に展開され、別々の引数として渡されます。 'zip()'関数は、それぞれの引数の要素を対応するインデックス(すべての最初の引数と同じように、すべての2番目の引数など)に結合します。したがって、必要な結果が得られます。これを答えで更新しました。 –

1

変更

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

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

に、それは何をやっている

+0

リストのリストにもっと多くの要素があると、それは機能しません。例えば[[1,2,3,4]、[5,6,7,8]、[9,10,11、 12]] –

0

あなたがfor i行を変更した場合:

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

それは期待される結果を与えます。あなたのコードは、唯一のn行mリストにoff by one error ;-)

関連する問題