본문 바로가기
Language & Tool/Python

🐍입출력 기본정리(input, print)

by 박수무당벌레 2025. 6. 9.

관련글 :

buffer.read 사용 (각각 1번 / 2번 문제 참고) https://waydd.tistory.com/142
https://waydd.tistory.com/199
strip, split https://waydd.tistory.com/35
언팩 https://waydd.tistory.com/86

 

 

1. 입력 메서드, 함수

 

- input

  •  input() 은 Python 내장 함수지만 내부적으로 표준 입력 스트림(sys.stdin)을 활용하여 입력을 받음
  • 콘솔에 출력(prompt) 후 사용자로부터 입력값을 받아 문자열로 반환
  • 한 줄씩 읽음(sys.stdin.readline()을 호출) + 내부에서 디코딩(바이트 스트림을 UTF-8 문자열로 바꾸기) + 문자열 뒤의 개행(\n) 제거(strip)  (가장 느림)
    → 입력이 수천개 수준 (10^3 이하) 일때 사용
  • 문자열 입력량이 많거나 반복 입력이 많을 경우, sys.stdin.readline()이 성능상 유리 (개행 문자 자동 제거되고 느림)
표현식 : input([prompt: Optional[str] = None, /]) -> str
# 예시
name = input("이름을 입력하세요: ")
print("안녕하세요,", name)
※ / 매개변수 (위치 전용 매개변수)
함수 정의에서 /기호 앞에 있는 매개변수들은 반드시 위치 인자(positional argument)로만 넘겨야 한다는 의미
- input("이름을 입력하세요: ") # 권장
- input(prompt="이름을 입력하세요: ") # 문서상으로는 금지
→ 내장 함수들은 C언어로 구현되어 있어서 키워드 인자를 받을 준비가 안 된 경우가 많음

 

 

- sys.stdin.readline

  • sys.stdin이라는 입력 스트림 객체 (TextIOWrapper)에 종속되어, 입력을 한줄 읽어오는 메서드 (줄단위 입)
    → 파일 객체도 내부적으로 TextIOWrapper이기 때문에 사용 가능
  • input 함수와 다르게 개행을 제거하지 않고 줄 끝에 개행 문자 (\n)가 포함 → 직접 .strip() 이나 .rstrip(_ 호출이 필요
  • 한 줄씩 읽지만 디코딩만 함 (strip 같은 후처리를 안 해서 조금 더 빠름)
  • 상대적으로 빨라 반복/대량 입력 처리에 적합 
    입력이 수만 ~ 수십만 일때 사용 (10^5 이상이면 사실상 필수)
표현식 : sys.stdin.readline([size: int = -1, /]) -> str
# 예시
s = sys.stdin.readline().strip()  # 개행 문자 제거

# 한 줄에서 여러 개의 정수 입력받기
a, b, c = map(int, sys.stdin.readline().split())  

# n개의 줄을 입력받아 리스트에 저장
n = int(sys.stdin.readline().strip())  # 첫 줄에서 개수 입력받기
arr = [sys.stdin.readline().strip() for _ in range(n)]
※ map 사용시 주의 사항
공백이 있는 입력이라면(ex. "0 1 1 0 1") 반드시 split() 으로 토큰(쪼갤 수 없는 기본 단위) 을 나눠서 사용해야함

 

 

- sys.stdin.buffer.read

  • 입력 전체를 바이트 단위 로 한번에 읽어오기  (바이트 스트림)
    → raw 를 통해 확인하면 byte literal(바이트 리터럴) 표시가 붙어있음, 변환/가공 필수 ( split(), map() 사용 )
     문자열이 아니라 bytes (b'123\n~~' 형식)
  • 이후 split()으로 파싱(토큰 단위 나누기) , 줄바꿈도 공백 취급 (split() 시 자동 제거)
    → 줄 경계 정보가 사라지기 때문에 주의
    → 줄 단위 구분 없이 공백으로 나열됨   ex) 4 2 /n 1 1 1 1 → [b'4', b'2', b'1', b'1', b'1', b'1']
  • 함수 호출이 1회 → 상수항이 작아 빠름 (입력량 많을수록 유리)
  • . split()로  나누고  map(int, ..) 같은 걸로 변환(숫자 등) 해서 사용
  • 대용량 입력, 줄 구분 불필요할때 사용
    → 입력 줄 수 10만 ~ 100만 줄 이상 혹은 총 입력 데이터 크기 10MB ~ 50MB 이상
    → 각 연산당 시간 제한이 1~2초 수준으로 촉박할 때
표현식 : sys.stdin.buffer.read(size: int = -1, /) -> bytes
# 예시
data = list(map(int, sys.stdin.buffer.read().split()))  # list[bytes]

# 순서대로 꺼내쓰기 위해 iterator 생성
it = iter(data) 
item = next(it)
...
items = [next(it) for _ in range(N)]

# EOF까지 모두 읽기
print(data)

 

 

- sys.stdin.read

  • 입력을 빠르게 여러 줄 읽기
    → 이미 문자열 로 디코딩, split 로 공백류 구분자로 처리
  • 입력 개수가 명확하지 않거나 EOF(End of File)까지 읽고 싶을 때 사용
표현식 : sys.stdin.read([size: int = -1, /]) -> str
# 예시
data = sys.stdin.read().splitlines() # 마지막 개행은 무시
data = sys.stdin.read().split('\n')  # 마지막이 개행이면 빈문자열 '' 이 추가

# 5바이트만 읽기
sys.stdin = open(0, 'rb')  # binary 모드로 재설정 (예시)
data_5 = sys.stdin.read(5)
print(data_5)  # 예: b'4 2\n
※ .splitlines() : 한 번에 읽어서 개행 문자 기준으로 나누기

 

 

2. 출력 메서드, 함수

 

- print

  • 표준 출력 장치(보통 콘솔)에 문자열이나 값을 출력하는 내장 함수로, 반환값은 None (반환하지 않음)
  • 내부적으로는 표준 출력(stdout) 문자열을 활용하는 함수로, 이는 C 언어의 printf() 또는 fputs()에 해당
    → print()는 단순히 sys.stdout.write(...)를 감싼 Wrapper 함수
  • 여러 인자를 쉼표로 구분하여 출력 가능
  • 기본적으로 끝에 개행 문자가 포함되어 자동으로 줄바꿈이 됨
  • 디버깅, 결과 출력, 파일 출력 등에 사용
표현식 : print(*objects[, sep=' ', end='\n', file=sys.stdout, flush=False])
※ 매개변수 의미
- *objects : 출력할 값들 (여러 개 가능)
- sep : 값 사이 구분자 (기본 ' ')
- end : 출력 후 끝에 붙을 문자열 (기본 \n 줄바꿈)
- file : 출력 대상 (기본 sys.stdout)
- flush : 버퍼를 강제로 비울지 여부 (기본 False)
※ 출력 대상 변경 
sys.stdout 을 다른 파일 객체로 바꾸면 print()의 대상도 바뀜 (Wrapper 함수이기 때문에)
  with open("out.txt", "w") as f:
  sys.stdout = f
  print("파일에 출력됨") # out.txt에 저장됨
※ tip!
- (예시) 아래는 입력 크기 N=100만, 쿼리=100만 기준 속도 차이
  → list + join 출력 : 약 1.1초
  → array + join 출력 : 약 1.15초
  → print 반복 출력 : 3.8초 (시간 초과 위험)
-  list(range(n+1))  : C 레벨에서 최적화 (빠름)
-  [1] * (n+1)  : 역시 내부적으로 C에서 memcpy처럼 한 번에 복제 (효율적)
- 단순 print 반복 출력보다 결과를 모아서 join으로 한번에 출력 권장 혹은 언패킹 사용
  → 반복 출력 : O(N²)
  → join, *(언팩) : 둘다 O(N), join이 근소 우위

 

 

- sys.stdout.write

  • 표준 출력 스트림(sys.stdout)에 문자열을 직접 출력하는 메서드
  • 실제로 출력한 문자 수(int)를 반환
  • str 타입(문자열) 1개만 출력 가능하기 때문에 숫자나 리스트는 문자열로 변환이 필요함
  • 개행 문자를 직접 포함해야 줄바꿈이 가능
  • print()보다 속도 빠름
  • 출력이 수만 ~ 수십만 줄이라면, print 대신 " \n".join()sys.stdout.write()  로 한번에 쓰는 게 안전
표현식 : sys.stdout.write([s: str, /]) -> int
# 예시
sys.stdout.write("Hello, World!\n")  # 개행 문자 직접 추가해야 함

# 리스트를 한 줄에 공백으로 출력하는 경우
arr = [1, 2, 3, 4, 5]
sys.stdout.write(" ".join(map(str, arr)) + "\n")

 


3. 내용 정리

 

- strip 과 split 비교 예시

  • (예시) s = input() : 사용자가 "01101" 입력 + 엔터 → "01101\n"
  • s.strip() : 양쪽 공백 제거
    "01101", 즉 ['0','1','1','0','1'] (문자열 = 문자 배열)
  • s.split() : 줄 전체를 그대로 하나의 문자열 토큰으로 인식
    → "01101\n" 은 공백(스페이스) 없음 + 마지막에 개행만 있음, ∴ ["01101"]
  • 둘의 list(map(int, s) 결과값은 다름
    strip() 사용 : [0,1,1,0,1]  (정수 배열)
    split() 사용 : [1101]        ( 01101를 정수화 )

 

- 줄바꿈 출력 3가지 방법

# 루프 
for s in sizes:
    print(s)

# join
print("\n".join(map(str, sizes)))

# 언패킹
print(*sizes, sep="\n")

 

 

- 입출력 정리

  • 문자열 입력 (단일) : s = sys.stdin.readline().strip()
  • 정수 입력 (단일) : n = int(sys.stdin.readline())
  • 공백 구분 여러 개 정수 입력 : a, b, c = map(int, sys.stdin.readline().split())
  • 리스트로 여러 개 정수 입력 : arr = list(map(int, sys.stdin.readline().split()))
  • 여러 줄 입력 : lines = [sys.stdin.readline().strip() for _ in range(n)]
  • 입력 끝까지 읽기 (바이트열) : data = list(map(int, sys.stdin.buffer.read().split()))
  • 입력 끝까지 읽기 (문자열) : data = sys.stdin.read().splitlines()
  • 빠른 출력 : sys.stdout.write("\n".join(map(str, arr)) 혹은 print
    → 결과에 대해 print 반복 출력 보다는 list에 모았다가 join 권장
  • print 개행, split 공백, strip(양쪽 없애기) 공백