pythonで2次元配列の斜めの要素を取り出す

## 例
![Screenshot 2023-04-14 11.14.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2586059/670765dd-11ea-e16d-1e5e-71140a2e80a1.png)

```python
array = [[1, 2, 3, 4, 5],
         [4, 5, 6, 7, 8],
         [4, 5, 6, 7, 8],
         [4, 5, 6, 7, 8],
         [7, 8, 9, 8, 7]]

n = len(array)
```

## リスト内包表記
```python
# 右下→左上
rl_d = [[array[max(0, -d) + i][max(0, d) + i] for i in range(n - abs(d))] for d in range(1-n, n)]
print(rl_d)
```
```python
>> [[7], [4, 8], [4, 5, 9], [4, 5, 6, 8], [1, 5, 6, 7, 7],
    [2, 6, 7, 8], [3, 7, 8], [4, 8], [5]]
```
```python
# 左下→右上
lr_d = [[array[max(0, d) + i][min(n + d, n) - i - 1] for i in range(n - abs(d))] for d in range(1 - n, n)]
print(lr_d)
```
```python
>> [[1], [2, 4], [3, 5, 4], [4, 6, 5, 4], [5, 7, 6, 5, 7],
    [8, 7, 6, 8], [8, 7, 9], [8, 8], [7]]
```

## 普通のfor文
```python
# 右下→左上
rl_d = []
for d in range(1 - n, n):
    diagonal = []
    for i in range(n - abs(d)):
        diagonal.append(array[max(0, -d) + i][max(0, d) + i])
    rl_d.append(diagonal)
print(rl_d)
```
```python
>> [[7], [4, 8], [4, 5, 9], [4, 5, 6, 8], [1, 5, 6, 7, 7],
[2, 6, 7, 8], [3, 7, 8], [4, 8], [5]]
```
```python
# 左下→右上
lr_d = []
for d in range(1-n, n):
    diagonal = []
    for i in range(n - abs(d)):
        diagonal.append(array[max(0, d) + i][min(n + d, n) - i - 1])
    lr_d.append(diagonal)
print(lr_d)
```
```python
>> [[1], [2, 4], [3, 5, 4], [4, 6, 5, 4], [5, 7, 6, 5, 7],
[8, 7, 6, 8], [8, 7, 9], [8, 8], [7]]
```

## 解説
:::note warn
注意
解説では右下→左上のパターンしかやってません！
:::

まず2次元配列を以下の写真のようにインデックス番号を振って考えます！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2586059/8e79289b-1ad9-0340-7d7c-d53e1017742d.png)

つまり要素の座標(x, y)は↓↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2586059/f5a4ed71-5383-f43e-db58-c026d95d70a0.png)
このようになります！

この座標を使ってとっていきたい斜めの要素を表すと、右下→左上の場合次のようになります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2586059/f5f6ec3c-8936-b3a3-a0af-dbee3b5d69ab.png)

xとyで分けてみます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2586059/47332e65-574b-5a45-a7c2-4a07edbc4091.png)
これでかなりイメージしやすくなったのではないでしょうか
あとは横方向と縦方向の2軸に分けて繰り返し処理をしていく方法を考えるだけです！

#### x座標
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2586059/8a7d603a-8b16-5171-455b-7997015b3d5c.png)

`n - |d|`は絶対値ということです！pythonやと→`n - abs(d)`
`max(0, -d)`は0と-dの大きい方の値ということです！
このようにするとx座標の値は`max(0, -d) + i`で計算できることがわかります！
pythonで書くと↓↓
```python
n = 5 # 2次元配列の大きさ
for d in range(1 - n, n):
    print("------")
    for i in range(n - abs(d)):
        print(max(0, -d) + i)
```

#### y座標
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2586059/73c150b4-891c-9753-5d90-71c0213661f2.png)

内容は同じなので省きますが、y座標は`max(0, d) + i`で確定しそうですね
pythonで書くとこんな感じです↓↓
```python
n = 5
for d in range(1 - n, n):
    print("------")
    for i in range(n - abs(d)):
        print(max(0, d) + i)    
```

#### x,y座標合わせる
```python
n = 5

for d in range(1-n, n):
    print('----------')
    for i in range(n - abs(d)):
        print("x, y =", max(0, -d) + i, max(0, d) + i)
```
出力
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2586059/bd80ab6b-b35f-991a-a688-0ad11571ae4e.png" width="20%"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2586059/05fa4df8-5671-d985-1b7b-c098c00ce398.png" width="60%">

出力値を見るとちゃんと斜めの要素の座標を生成できていることがわかります！
最後にこれは座標（インデックス番号）なので、2次元配列の要素を取得しましょう！
`array[x][y]`という感じになっていればオッケーなので、
```python
array[max(0, -d) + i][max(0, d) + i]
```
これで値を取れたので、配列に格納すれば終わりっていう感じです！
あざした〜