2차원 배열의 움직임을 바라보는 함수(Python)

소개



경쟁 프로 중 2차원 배열의 변화를 관찰하고 싶을 때가 있습니다.
DP라든지, DP라든지.

1차원 배열이라면 아직도, 2차원 배열을 순차 print 그러면 꽤 보기 어렵기 때문에,
2차원 배열의 변화를 가만히 바라보는 함수를 준비했습니다.

완성품은 이쪽↓
from time import sleep
def print_2d_overwrite(list2d, val_width=5, sleep_sec=1.0, header=None, highlights=[]):
    res_str = f'{header}\n' if header is not None else '' 
    for i, row in enumerate(list2d):
        for j, v in enumerate(row):
            v_str = str(v).rjust(val_width)
            if (i,j) in highlights: 
                v_str = f'\033[31m{v_str}\033[0m'
            res_str += f' {v_str}'
        res_str += '\n'
    new_line_cnt = res_str.count('\n')
    res_str += f'\033[{new_line_cnt}A'
    print(res_str, end='')
    sleep(sleep_sec)

# --- sample ---
n = 3
list2d = [ [0]*n for _ in range(n)]
for i in range(n):
    for j in range(n):
        list2d[i][j] = 3**(i+j)
        print_2d_overwrite(list2d, val_width=3, header=(i,j), highlights=[(i,j)])

동작의 모습은↓


포인트는 다음과 같습니다.
  • 표준 출력 덮어쓰기
  • 값의 길이 (표시 자리수)를 정렬
  • 문자열의 색상 변경
  • sleep한다 ( time.sleep() 하는 것만 )

    (2020/11/19 추가)
    코멘트로, 기술적인 쓰는 방법을 받았습니다.

    표준 출력 덮어쓰기



    관련 기사 가 어제 투고되고 있어 깜짝.
    자신이 구현의 참고로 한 기사는 여기 입니다.
    이러한 기사로 해설은 충분하기 때문에, 이번은 요점만 설명.
    \033[nA 에서 커서를 n 행 위로 이동할 수 있습니다.
    표시하고 싶은 2차원 배열을 캐릭터 라인 (res_str) 로 변환해, 그 안의 개행 \n 의 개수를 세어, 캐릭터 라인의 마지막에 추가하고 있습니다. f 문자열을 사용하면 편합니다.print 에서 end='' 를 잊지 마세요.
    new_line_cnt = res_str.count('\n')
    res_str += f'\033[{new_line_cnt}A'
    print(res_str, end='')
    

    값의 길이(표시 자리수)를 정렬



    이런 느낌으로 길이가 갖추어지지 않으면보기 어렵다.
    3  5  345
    235  -48  123
    1  2  3
    

    그래서 각 요소의 길이 (표시 자리수)를 정렬하고 싶습니다.
        3     5   345
      235   -48   123
        1     2     3
    

    이번에는 str.rjust(n) 를 이용하여 이것을 실현합니다.
    문자열을 오른쪽에 맞추고, n 문자가 부족한 분은 제 2 인수로 지정한 문자로 채웁니다 (아무것도 지정하지 않는 경우는 스페이스 메우기).
    v_str = str(v).rjust(val_width)
    

    문자열의 색상 변경


    \033[31m色変したい文字列\033[0m 에서 OK입니다.30m ~ 37m 에서 색상 설정 가능. 31m는 빨간색입니다.
    (자세한 내용은 여기)

    함수 내에서 highlights에 지정된 값의 색상을 변경하고 있습니다. 이쪽도 f 문자열을 사용하면 편합니다.
    if (i,j) in highlights: 
        v_str = f'\033[31m{v_str}\033[0m'
    

    결론



    어쩌면 디버그에서 사용할 수 있을지도 모르기 때문에, 경프로용 스니펫에 가세해 두었습니다.sleep 의 부분을 키 입력으로 하면 좀 더 편리할지도 생각했습니다만, Mac이라고 sudo 하지 않으면 keyboard 가 사용할 수 없고 귀찮았으므로, 이대로.
  • 좋은 웹페이지 즐겨찾기