

#### 質問事項

下記のような **期待するデータ** にするにはどのような処理を組めば実現できますでしょうか？

[code]

    # 対象データ
    test_list = [
        ['.', '.', '.'],
        ['.', '#', '.'],
        ['.', '.', '.']
    ]
    
    
    # 期待するデータ
    test_list = [
        ['.', '#', '.'],
        ['#', '#', '#'],
        ['.', '#', '.']
    ]
    
[/code]

#### 試した処理

以下に自分が試した処理を記載します。  
ただ、これでは一部期待する値が代入されてないのと、余分なところに値が代入されてしまいます。

現段階では解決策が見つからなく、もしお分かりの方がいましたらご教示よろしくお願いいたします。

[code]

    # 対象データ
    test_list = [
        ['.', '.', '.'],
        ['.', '#', '.'],
        ['.', '.', '.']
    ]
    
    for i in range(len(test_list)):
        for j in range(len(test_list)):
            try:
                if test_list[i][j+1] == '#' or test_list[i][j-1] == '#' or test_list[i-1][j] == '#' or test_list[i+1][j] == '#':
                    test_list[i][j] = '#'
            except IndexError:
                pass
    print(test_list[0])
    print(test_list[1])
    print(test_list[2])
    
    # 出力結果
    ['.', '#', '.']
    ['#', '#', '.']
    ['#', '#', '.']
    
[/code]


CC BY-SA 4.0
2022-08-30T12:18:31.337
90840
2022-09-16T01:19:10.487
2022-08-30T12:47:26.490
3060
47752
question
python python3
多次元配列である特定の要素を基準として、その上下左右に値を入れたい


複数`#`が存在する可能性も考え下記のようなコードではどうでしょうか？

[code]

    test_list = [
        ['.', '.', '.'],
        ['.', '#', '.'],
        ['.', '.', '.']
    ]
    
    indexes = []
    for i in range(len(test_list)):
        for j in range(len(test_list[0])):
            if test_list[i][j] == "#":
                indexes.append((i-1,j))
                indexes.append((i,j-1))
                indexes.append((i,j+1))
                indexes.append((i+1,j))
                
    for (i, j) in indexes:
        try:
            test_list[i][j] = "#"
        except IndexError:
            pass
    print(test_list)
    
[/code]


CC BY-SA 4.0
2022-08-30T12:46:13.043
90841
2022-08-30T12:46:13.043
39819
90840
answer


numpy を使っても良いのであれば

[code]

    def set_closs(lst, s):
        import numpy as np
        ary = np.array(lst)
        for idx in zip(*np.where(ary==s)):
            ary[max(0,idx[0]-1):idx[0]+2, idx[1]] = ary[idx]
            ary[idx[0], max(0,idx[1]-1):idx[1]+2] = ary[idx]
        return ary.tolist()
    
    # 対象データ
    test_list = [
        ['.', '.', '.'],
        ['.', '#', '.'],
        ['.', '.', '.']
    ]
    
    out_list = set_closs(test_list, '#')
    print(*out_list, sep='\n')
    """
    ['.', '#', '.']
    ['#', '#', '#']
    ['.', '#', '.']
    """
    
    test_list = [
        ['.', '.', '.', '.'],
        ['.', '#', '.', '.'],
        ['.', '.', '#', '.'],
        ['.', '.', '.', '.']
    ]
    out_list = set_closs(test_list, '#')
    print(*out_list, sep='\n')
    """
    ['.', '#', '.', '.']
    ['#', '#', '#', '.']
    ['.', '#', '#', '#']
    ['.', '.', '#', '.']
    """
    
[/code]


CC BY-SA 4.0
2022-08-30T14:59:38.957
90843
2022-08-30T14:59:38.957
41756
90840
answer


scipyの`binary_dilation()`を使うと簡単です。  
[scipy.ndimage.binary_dilation — SciPy
Manual](https://docs.scipy.org/doc/scipy/reference/generated/scipy.ndimage.binary_dilation.html)

[code]

    import numpy as np
    from scipy.ndimage import binary_dilation
    
    def set_closs(lst, s):
        arr = np.array(lst)
        arr[binary_dilation(arr == s)] = s
        return arr.tolist()
    
[/code]


CC BY-SA 4.0
2022-09-16T01:19:10.487
91127
2022-09-16T01:19:10.487
37167
90840
answer