[Python] Data Types, Sequence Type, Strings, input(), for loop

jiggyjiggy·2022년 4월 3일
0
post-thumbnail


https://docs.python.org/3/reference/datamodel.html#the-standard-type-hierarchy

input 함수가 입력값을 왜 문자열(String)으로 받는지 생각해보셨나요?

여러분은 input 함수가 입력값을 왜 문자열 형(Strings type)으로 받는지 생각해보셨나요?
제가 경험했던 문제점을 바탕으로 같이 생각해 보아요

경험한 문제

알고리즘 문제를 풀던 중 경험했던 문제였습니다
입력값으로 연달아 들어오는 숫자를 하나씩 떼어서 for 문(statement)을 돌리기 위한 입력값 처리 방법으로 다음과 같은 logic을 세웠습니다

Logic

  • 입력값
    010

숫자를 하나씩 for 문으로 돌리기 위해 list 형으로 받고자 했다
1. 입력값이 010 로 주어질 때
2. 0, 1, 0 로 각 자리 수에 해당하는 숫자를 써야했다.
3. 따라서 list(map(int, input().split()))을 사용하여
4. [0, 1, 0] 로 list로써 저장하고, 요소(element)는 int형으로 저장하고자 했다

  • 원하는 저장값
    [0, 1, 0]

"여러분들도 이상없어보이죠?"
"저만 이상없어보이는거 아니죠?"

문제의 code

input_split_ = input().split()	# 입력값: 010
result = list(map(int, input_split_))	# result에 저장된 값: [1, 0]

result에 [0, 1, 0]로 할당될 것으로 예상했지만...

  • 확인해본 저장값
    [1, 0]

"???"
"맨 앞의 0이 어디로 갔지?"


내가 세운 code를 분석해보자면

입력값이 010 일때, 10 으로 처리되는 부분은 다음과 같았습니다

input_split_ = input().split()	# 입력값: 010
a = (list(map(int, input_split_)))
print(a) # [1, 0]

print(input_split_) # ['010']  # 각 요소는 str 타입으로 받고 list로 묶음
print(type(input_split_)) # <class 'list'>
  1. input().split()으로 한줄의 입력값(ex. 010)을 받는다면

  2. 입력을 “010” 문자열로 받고 list로 저장하고

  3. map()으로 “010" 문자열을 int로 형변환 하여 10 으로 처리하고

  4. list에 저장합니다

  • 분석
    입력을 “010” 문자열로 받고, 요소 1개("010")를 int 형변환 하니깐 10이 되었구나...
    "0", "1", "0"이 아니라 "010"으로 받아졌구나,,
    입력값이 한 개 일때 숫자를 각 자리수로 받아야하는데... 어떻게 처리해야 하지?

map(int, input().split()) 그리고 for 문

map(int, input().split())

map(int, input().split())

"다시 초심으로 돌아가서 입력 함수를 분석 해 보았습니다"

map()

별표 "근데 input 함수로 받으면 문자열이 되는데?"

생긴 의문점: "문자열이 iterable 했나?"

input()

split()

해결(?):"아하 split 함수로 list로 반환 됐나보구나"

근본적 해결도 아닐뿐더러
문자열도 iterable 하다

for 문(statement)

보통 for loop 쓰면

>>> for i in range(5):
...     print(i)
... 
0
1
2
3
4

위와 같이 "range()"와 같이 관습적인 형태들을 쓰는 경우가 많을 것입니다

for 문에 쓸 수 있는 data type

공식 문서를 참조해보면 sequence type의 자료형(data type) 혹은 iterable 객체를 쓸 수 있다고 써있습니다.

즉, for 문에 string, tuple, list 와 그 이외의 iterable 객체를 쓸 수 있는 것입니다.

쉽게 말하자면, sequence type인 자료형은 iterable 이라고 생각하면 됩니다.

  • 이 사건을 계기로 개별 자료구조 자체만의 이해가 아닌
    data type 별로 해당 type이 갖는 특성 자체를 계기가 되었습니다

data type으로 공부하는 자료구조의 특성 이해 (list, tuple, set, dictionary) 링크



input 함수가 입력값을 왜 문자열로 받는지 눈치 채셨나요?

그건 for 반복문(loop statement)와 관련 있었습니다

input 함수와 관련해서 숫자를 입력해도 형변환을 따로 해줘야 하기 때문에 귀찮았던 경험이 존재 할 것 입니다

>>> a = input() 
5
>>> type(a) 
<class 'str'>
>>> b = int(input())
3
>>> type(b)
<class 'int'>

입력값이 숫자형으로 처리된다면 생기는 문제

입력값을 숫자를 숫자형(numeric type)으로 받게된다면
숫자형들은 container 도 아니고, immutable 이기 때문에 가공이 어렵습니다

container 객체는 list, tuple, set, dictionary 과 같이 다른 자료형의 객체를 요소로 저장할 수 있는 객체를 말합니다
container 링크

1개의 숫자 0123456 을 각 자리 수의 숫자값을 따로 저장하려면 어떻게 처리해야 할까요?

코딩을 하다보면 처리해야할 숫자가 연속적으로 입력되는 경우가 많습니다
대표적인 두 유형에 대해 보겠습니다

입력값 유형

1. 입력값이 한 개 일때

또한 아래의 경우 처럼 공백문자도 없이 연달아 들어오는 경우도 빈번합니다
이를 입력값이 한 개 일때로 분류하겠습니다

01001000111

이러한 경우 입력값이 숫자형으로 처리된다면 각 자리의 숫자를 개별적으로 저장하는 것부터가 문제일 것입니다.

2. 입력값이 공백을 기준으로 여러 개 일때

컴퓨터에 입력값이 한개씩 들어옵니다
이를 입력값이 공백을 기준으로 여러 개 일때로 분류하겠습니다

0 1 0 0 1 0 0 0 1 1 1

입력값이 숫자형으로 처리된다면 공백 문자의 처리 함수도 있어야 할 것이고
처리해도 결국 1번 유형으로 귀결되기 때문에 각 자리의 숫자를 개별적으로 저장하기 어렵습니다.

따라서 input 함수는 입력값을 문자열로 처리하는 것 입니다


입력값을 문자열로 처리한다면?

for 문에서 문자열을 지원하기 때문에 바로 각 자리의 숫자를 개별적으로 처리 할 수 있습니다.

>>> for i in "0123456":
...     print(i)
... 
0
1
2
3
4
5
6

for 문을 위한 입력 유형에 따른 올바른 처리방법

input() 함수 그대로 사용하면 됬던 것 이었습니다

"결국 돌고 돌아서 기본으로 돌아오니, 로섬 형님의 배려심에 감탄했습니다"
"기본에 충실해 보면, 필요한 것이 다 구현되어있는 것이 python 인 것 입니다!"

1. 입력값이 한 개 일때(ex. 010)

input_ = input()	# 입력값: 010

print(input_)	# "010"
print(type(input_))	# <class 'str'>
>>> for i in input_:
...     print(i)
... 
0
1
0

입력값이 한 개 일때는, input() 함수 그대로 사용하여 문자열로써 한글자씩 iterator로써 for 문을 처리하면 됐던것 입니다.

2. 입력값이 공백을 기준으로 여러 개일때 (ex. 0 1 0)

input_ = input().split()	# 입력값: 0 1 0
print(input_)	# ['0', '1', '0']
print(type(input_))	# <class 'list'>
>>> for i in input_:
...     print(i)
... 
0
1
0

입력값이 공백을 기준으로 여러 개일때는, input().split()으로 숫자 하나씩 list로의 요소로 저장하여 각 요소를 iterator로 for 문을 처리 하면 됐던 것 입니다


다시, 문제의 그 logic

다시 처음의 로직을 돌아보면

본 문제에서는 입력값을 for 문으로 돌리기 위해 list 형으로 받고자 했다

for 문을 돌리기 위해 list 형으로 받는 것도 이상하고...

  1. 입력값이 010 로 주어질 때
  2. 0, 1, 0 로 각 자리 수에 해당하는 숫자를 써야했다.
  3. 따라서 list(map(int, input().split()))을 사용하여
  4. [0, 1, 0] 로 list로써 저장하고, 요소(element)는 int형으로 저장하고자 했다

"한 개의 입력값"을 "input().split()"으로 받으려는 것 부터 이상해보이지 않나요? ㅎㅎ


그래도... list에 숫자형으로 요소에 저장하고 싶다면

1. 입력값이 한 개 일때(ex. 010)

list(map(int, input()))
하나의 문자열(strings)로 저장

input_ = input()	# 입력값: 010
result = (list(map(int, input_)))
print(result)    # [0, 1, 0]

print(input_)     # 010
print(type(input_))     # <class 'str'>
  1. 입력을 input() 을 통해
  2. 문자열(iteration) 1개로 받았기에
  3. map()으로 문자열의 한글자씩(iterator)
  4. int로 형변환 후
  5. list에 넣음

2. 입력값이 공백을 기준으로 여러 개일때 (ex. 0 1 0)

list(map(int, input().split()))

보통의 문제에서 입력값이 공백을 기준으로 입력됩니다 (ex. 0 1 0)

input_split_ = input().split()	# 입력값: 0 1 0
result = (list(map(int, input_split_)))
print(result)     # [0, 1, 0]

print(input_split_)     # ['0', '1', '0']  # 각 요소는 str 타입으로 받고 list로 묶음
print(type(input_split_))   # <class 'list'>
  1. 입력을 input().split()을 통해
  2. 각 요소를 문자열(iteration)로 받고, list로 저장
  3. map()으로 list의 요소 하나씩(iterator)
  4. int로 형변환 후
  5. list에 저장합니다.

profile
궁금증 주도 공부 / 원리 파고들기 / 경험에 기반한 블로그

0개의 댓글