introduction
競技プログラミングの問題を解いていた際に用いた方法について書いていきます。
配列の任意の部分を参照する処理について記述します。
誤っているところがあればコメント等よろしくお願いします。
配列の準備
下記で任意の2次元配列をnumpyを用いて作成しました。
importnumpyasnparray=np.arange(16).reshape((4,4))#データを準備
>>>array([[0,1,2,3],[4,5,6,7],[8,9,10,11],[12,13,14,15]])
配列の任意部分を参照する処理
例えば下記に示すような任意の赤丸で囲った配列を参照したいとき
pythonで実装すると以下のようにできると考えました。
div_array=[]foriinrange(1,3):tep_array=[]forjinrange(1,3):tep_array.append(array[i][j])div_array.append(tep_array)print(div_array)#div_array=[[5, 6], [9, 10]]
ただ、この方法だと記述量も多く、変数をたくさん置く必要があって読みにくいです。
それを解決するために、ndarray型配列であれば、スライスを用いることで実装できます。
(ただしpython のlistでlist[1:3,1:3]と指定するとエラーがおきます。)
div_array=array[1:3,1:3]>>>div_array([[5,6],[9,10]])
まず、左側の1:3で行方向の参照を行い、
[ 4, 5, 6, 7] と[ 8, 9, 10, 11]の行を参照します。
次に、右側の1:3で列方向の参照ができます。
よって、[5,6] と [9,10] が参照できます。
ただ、この場合、コピーではなく、参照ですので、div_arrayを変更すると参照元のarrayも変更してしまいます。
参照元の配列を変更したくない場合は、
div_array=array[1:3,1:3].copy()
と記述することで解決できます。
追記:list内listをprint()するときの豆知識
話が少し逸れますが、list内の要素を順番に出力する際には
以下のようにすることが多いと思います。
foriindiv_array:print(i)#[5 6]
#[ 9 10]
ただしlistの[]が表示されていると不正解になることもあり、これを防ぐために以下のように実装を試みました。
引数の end="" にスペースを指定し、5と6 をスペースで分割してその後の空のprint()で次の行に移ることを試みました。
foriindiv_array:forjini:print(j,end=" ")print()>>>56#6、10の後にスペースが入っている
>>>910#6、10の後にスペースが入っている
ですが、この実装では6と10の後にもスペースが入ってしまい不正解となりました。
これを解決するために以下のようにすれば、簡単に解決することができました。
[ ]を外したいリストの前に*をつけて出力することによって、リスト内リストの各要素を分割して表示することができました。
foriindiv_array:print(*i)>>>56>>>910
まとめ
今回は2次元配列から任意の配列を参照する方法と、2次元リストの出力のことに関して述べました。
かなりマニアックな内容ですが使ってみてください。