Unit 24. 문자열 응용하기

문자열도 문자 여러개가 연속적으로 이어져 있는 시퀀스 자료형이기 때문에 리스트와 비슷하게 사용할 수 있다.

 

24.1 문자열 조작하기

24.1.1 문자열 바꾸기

replace('바꿀 문자열', '새 문자열')의 형식으로 문자열 안의 문자열을 다른 문자열로 바꾼다. 문자열 자체는 바뀌지 않으며 바뀐 결과를 반환한다.

바뀐 결과를 유지하고 싶다면 문자열이 저장된 변수에 replace를 사용한 뒤 다시 변수에 할당해 준다.

 

24.1.2 문자 바꾸기

translate는 문자열 안의 문자를 다른 문자로 만든다. 이것을 사용하기 위해서는 먼저 str.maketrans('바꿀 문자', '새 문자')로 변환 테이블을 만든다. 그 후 translate(테이블)을 사용하면 문자를 바꾼 뒤 결과를 반환한다. 

다음과 같은 경우는 a,e,i,o,u를 각각 1,2,3,4,5로 바꾼다. 

 

24.1.3 문자열 분리하기

split()은 공백을 기준으로 문자열을 분리한다. 또한 괄호 안에 기준 문자열을 지정하면 그 문자열을 기준으로 문자열을 분리한다.

위의 경우 콤마와 쉼표를 기준 문자열로 지정해서 ', '을 분리하여 단어만 리스트로 만든다.

 

24.1.4 구분자 문자열과 문자열 리스트 연결하기

리스트로 분리된 문자열을 다시 연결하여 문자열로 만드는것도 가능하다. join(리스트)로 구분자 문자열과 문자열 리스트의 요소를 연결하여 하나의 문자열로 만든다. 다음은 공백 ' '에 join을 사용하여 각 문자열 사이에 공백이 들어가도록 한 것이다.

 

24.1.5 소문자를 대문자로 바꾸기

문자열의 문자를 모두 대문자로 바꾸려면 upper()를 사용한다. 문자열 안에 대문자가 있으면 그대로 유지된다.

 

24.1.6 대문자를 소문자로 바꾸기

문자열의 문자를 모두 소문자로 바꾸려면 lower()를 사용한다. 문자열 안에 소문자가 있다면 그대로 유지된다.

 

24.1.7 왼쪽 공백 삭제하기

lstrip()은 문자열에서 왼쪽에 있는 모든 연속된 공백을 삭제한다.

 

24.1.8 오른쪽 공백 삭제하기

rstrip()은 문자열에서 오른쪽에 있는 모든 연속된 공백을 삭제한다.

 

24.1.9 양쪽 공백 삭제하기

strip()은 문자열 양쪽에 있는 연속된 모든 공백을 삭제한다.

 

24.1.10 왼쪽의 특정 문자 삭제하기

lstrip('삭제할 문자들')의 형식으로 사용하면 문자열 왼쪽에 있는 해당 문자를 모두 삭제한다.

여기서는 공백을 지정하지 않았기 때문에 공백은 남아있다.

 

24.1.11 오른쪽의 특정 문자 삭제하기

rstrip('삭제할 문자들')의 형식으로 사용하면 문자열 오른쪽에 있는 해당 문자를 모두 삭제한다.

 

24.1.12 양쪽의 특정 문자 삭제하기

strip('삭제할 문자들')의 형식으로 사용하면 문자열 양쪽에 있는 해당 문자들을 삭제한다.

string 모듈의 punctuation에는 모든 구두점이 있다.

다음과 같이 strip()메서드에 string.punctuation을 넣어주면 문자열 양쪽의 모든 구두점을 삭제할 수 있다.

 

24.1.13 문자열을 왼쪽 정렬하기

ljust(길이)는 문자열을 지정한 길이로 만들고, 왼쪽으로 정렬한 후, 남는 공간을 공백으로 채운다.

문자열보다 길이를 작게 지정하면 다음과 같이 아무 변화 없다.

 

24.1.14 문자열을 오른쪽 정렬하기

rjust(길이)는 문자열을 지정한 길이로 만들고, 오른쪽으로 정렬한 후 남은 공간을 공백으로 채운다.

 

24.1.15 문자열을 가운데 정렬하기

center(길이)는 문자열을 지정한 길이로 만들고, 가운데 정렬하며 남는 공간은 공백으로 채운다. 다음의 경우 문자열의 길이를 10으로 만들어 가운데로 정렬한 뒤 양 옆의 남은 공간은 2칸씩 채운다.

남는 공간이 홀수가 된다면 왼쪽에 공백이 한 칸 더 들어간다.

 

24.1.16 메서드 체이닝

문자열 메서드는 처리한 결과를 반환하도록 만들어졌기 때문에 메서드를 계속 연결해서 호출하는 메서드 체이닝이 가능하다. input().split()도 메서드 체이닝이고, 다음 코드는 문자열을 오른쪽 정렬 한 뒤 대문자로 만드는 메서드 체이닝이다.

 

24.1.17 문자열 왼쪽에 0 채우기

zfill(길이)는 지정된 길이에 맞춰서 문자열의 왼쪽에 0을 채운다. 문자열의 길이보다 지정된 길이가 작다면 아무것도 채우지 않는다. 보통 숫자를 일정 자리수로 맞추고 앞자리를 0으로 채울 때 사용한다.

 

24.1.18 문자열 위치 찾기 

find('찾을 문자열')은 문자열에서 해당 문자열을 찾으면 위치 인덱스를 반환하고, 없으면 -1을 반환한다. 왼쪽에서 부터 문자열을 찾는데, 같은 문자열이 여러 개일 경우 처음 찾은 문자열의 인덱스를 반환한다.

 

24.1.19 오른쪽에서부터 문자열 위치 찾기

rfind('찾을 문자열')은 문자열에서 해당 문자열을 오른쪽에서부터 찾아서 찾으면 위치 인덱스를 반환하고, 없으면 -1을 반환한다. 같은 문자열이 여러개인 경우 먼저 찾은 인덱스를 반환한다.

 

24.1.20 문자열 위치 찾기

index('찾을 문자열')은 왼쪽에서 부터 해당 문자열을 찾아서 위치 인덱스를 반환하고, 없으면 에러를 발생시킨다. 해당 문자열이 여러개일 경우 처음 찾은 문자열의 인덱스만 반환한다.

 

24.1.21 오른쪽에서부터 문자열 위치 찾기

rindex('찾을 문자열')은 오른쪽에서부터 특정 문자열을 찾아서 인덱스를 반환한다. 문자열이 없으면 에러를 발생시키며, 해당  문자열이 여러개일 경우 처음 찾은 문자열의 인덱스만 반환한다.

 

24.1.22 문자열 개수 세기

count('문자열')은 현재 문자열에서 특정 문자열이 몇 번 나오는지 확인할 수 있다.

 

24.2 문자열 서식 지정자와 포매팅 사용하기

문자열 안에서 특정 부분을 원하는 값으로 바꿀 때 문자열 서식 지정자 또는 포매팅을 사용한다.

 

24.2.1 서식 지정자로 문자열 넣기

서식 지정자는 %로 시작하고, 자료형을 뜻하는 문자가 붙는다. %s는 문자열 이라는 의미이다. 문자열 안에 서식지정자(%s)를 넣고 그 뒤에 %를 넣고 뒤에 서식 지정자에 넣고 싶은 문자열을 지정한다. 

다음과 같이 문자열을 직접 지정하지 않고, 변수에 넣어 지정하는 것도 가능하다.

 

24.2.2 서식 지정자로 숫자 넣기

십진 정수를 의미하는 서식 지정자는 %d이다.

 

24.2.3 서식 지정자로 소수점 표현하기

실수를 넣을 때는 %f를 사용하며 고정 소수점의 f이다.(Fixed point) %f는 기본적으로 소수점 이하 6자리 까지 표현하며, 소수점 이하 자리수를 지정하고 싶으면 f 앞에 .(점)자리수 를 지정해주면 된다.

 

24.2.4 서식 지정자로 문자열 정렬하기

서식 지정자 % 뒤에 숫자를 넣으면 문자열을 지정된 길이로 만든 뒤 오른쪽으로 정렬하고 남는 공간을 공백으로 채운다.

%d 와 %f도 숫자와 조합하여 오른쪽으로 정렬시킬 수 있다.

%f의 경우 .(점) 앞에 정렬할 길이를 지정하고, 점 뒤에 소숫점 이하 자리수를 지정한다.

왼쪽 정렬은 문자열 길이에 -기호를 붙이면 된다. 

 

24.2.5 서식 지정자로 문자열 안에 값 여러 개 넣기

문자열 앞에 값을 두 개 이상 넣으려면 %를 붙이고, 괄호안에 값(변수)을 콤마로 구분해서 넣으면 된다. 괄호로 값을 묶지 않으면 에러가 발생한다. 

위 경우는 서식 지정자가 두개라 값도 두 개가 들어갔다. 값은 항상 서식 지정자와 개수를 맞춰줘야 한다. 만약 서식 지정자 둘을 붙이면 결과도 붙어서 나오므로 주의해야 한다.

 

24.2.6 format 메서드 사용하기

문자열 포매팅은 { }(중괄호) 안에 포매팅을 지정하고, format()메서드로 값을 넣는다.

{ } 안에는 인덱스를 지정하고, format()안에는 { }에 넣을 값을 지정하면 된다.

 

24.2.7 format메서드로 값을 여러개 넣기

{ } 안에 인덱스를 지정하고 format에는 인덱스가 증가하는 순서대로 값을 넣으면 된다. 문자열에는 인덱스 숫자에 해당하는 값이 들어간다.

format()안에 지정한 값은 인덱스를 0부터 순서대로 지정되며 { }안에 해당하는 인덱스 값에 들어간다.

 

24.2.8 format 메서드로 같은 값을 여러 개 넣기

다음과 같이 같은 인덱스가 지정된 { }가 여러개 있으면 같은 값이 여러 개 출력된다.

 

24.2.9 format 메서드에서 인덱스 생략하기

{ }에서 인덱스를 생략하면 format()에 지정한 순서대로 값이 들어간다.

 

24.2.10 format 메서드에서 인덱스 대신 이름 지정하기

{ } 안에 인덱스 대신 이름을 지정하고, format()에는 이름에 해당하는 값을 지정해주면 된다.

 

24.2.11 문자열 포매팅 변수를 그대로 사용하기

변수에 값을 넣고 { } 에 변수 이름을 지정하고 문자열 앞에 f를 붙이면 변수의 값을 { }에 불러올 수 있다.

{ } 중괄호 자체를 출력하려면 {{, }} 처럼 중괄호를 두번 사용하면 된다.

 

24.2.12 format 메서드로 문자열 정렬하기

다음과 같이 인덱스 뒤에 :(클론)을 붙이고 정렬할 방향과 길이를 지정해주면 된다.

'{인덱스:<길이}'.format(값)

 

부등호 방향이 왼쪽을 가리키고 있기 때문에 왼쪽으로 정렬하고 나머지 공간은 공백으로 채운다.

부등호 방향이 오른쪽을 가리킨다면 오른쪽으로 정렬하고 남는 공간은 공백으로 채운다.

인덱스를 지정하지 않고 클론 뒤에 방향과 길이만 지정해도 된다.

 

24.2.13 숫자 개수 맞추기

정수와 실수 앞에 0을 넣어서 숫자 개수를 맞출 수 있다. %d는 %와 d사이에 0과 숫자 자리수를 넣으면 자리수에 맞춰서 앞에 0이 들어간다. { }를 사용할 때는 인덱스나 이름 뒤에 클론을 붙이고, 03d처럼 0과 숫자 개수를 지정해주면 된다.

실수는 다음과 같이 .(점) 뒤에 소수점 자리수를 지정할 수 있다. 실수는 숫자 개수 부분에 정수 부분, 소수점, 실수부분이 모두 포함된다.

 

24.2.14 채우기와 정렬을 조합하여 사용하기

문자열 포매팅은 채우기와 정렬을 조합하여 사용할 수 있다. 다음과 같이 { }에 인덱스, 채우기, 정렬, 길이, 자릿수, 자료형 순서로 채운다.

'{인덱스:채우기 정렬(부등호) 길이.자릿수 자료형}'

길이를 10으로 만들고 왼쪽, 오른쪽으로 정렬한 후 남은 공간을 0으로 채운 것이다.

실수로 만들 것이면 다음과 같이 소수점 자리수와 실수 자료형 f를 사용하면 된다.

채우기 부분에는 0이 아닌 다른 문자가 들어가도 된다. 공백을 넣어도 되고, 아무 값도 지정되지 않으면 공백으로 처리하며, 다른 아무 문자나 넣어도 된다.

금액을 표현하기 위해 천 단위로 구분할때 format()함수에 숫자와 콤마를 넣어 간편하게 구분할 수 있다.

다음과 같이 서식 지정자와 함께 사용할수 있다. 

포매팅에서 콤마를 넣으려면 다음과 같이 클론 뒤에 콤마를 넣는다.

정렬을 사용하려면 정렬 방향과 길이 뒤에 콤마를 넣는다.

 

24.3 퀴즈

정답은 a, e 이다. count 는 문자열에서 지정한 문자열이 몇번 나오는지 세는 메서드이고, index는 왼쪽에서부터 찾는다.

정답은 d이다.

정답은 b,d이다.

정답은 c,d이다.

 

24.4 연습문제: 파일 경로에서 파일 명만 가져오기

정답은 다음 코드와 같다.

f_list = path.split('\\')
filename = f_list[-1]

경로를 \\를 기준으로 나누면 리스트가 생성된다 출력하고자 하는 내용은 리스트의 마지막 요소에 들어있기 때문에 filename에 -1 인덱스를 저장하면 된다.

 

24.5 심사문제 : 특정 단어 개수 세기

정답은 다음 코드와 같다.

s = input()

s_list = list(s.split())
cnt = 0

for i in s_list:
    if i.strip(',.') == 'the':
        cnt += 1

print(cnt)

입력된 문자열을 공백 기준으로 끊어서 리스트로 만들고, the에 .이나 ,가 붙어있을 수도 있기 때문에 ,.을 제거하고, the랑 비교해서 일치하면 숫자를 하나씩 누적하여 마지막에 누적된 숫자를 출력한다.

 

24.6 심사문제: 높은 가격 순으로 출력하기

정답은 다음 코드와 같다.

price = list(map(int, input().split(';')))

price.sort(reverse=True)

for i in price:
    print('{:>9,}'.format(i))


입력값을 정수로 된 리스트로 만들고, 내림차순으로 정렬한다. 이후 반복문으로 모든 요소들을 9자리로 만들고, 오른쪽으로 정렬하고, 천 단위로 콤마를 붙인다.

 

Unit 25. 딕셔너리 응용하기

25.1 딕셔너리 조작하기

25.1.1 딕셔너리에 키-값 쌍 추가하기

딕셔너리에 키-값 쌍을 추가하는 메서드는 다음 두 가지가 있다.

  • setdefault : 키-값 쌍 추가
  • update : 키의 값 수정, 키가 없으면 키-값 쌍 추가

25.1.2 딕셔너리에 키와 기본 값 저장하기

setdefault(키)는 딕셔너리에 키-값 쌍을 추가한다. setdefault에 키만 지정하면 값에 None을 저장한다. 

setdefault(키, 기본값)으로 지정하면 기본값을 저장한 뒤 해당 값을 반환한다.

 

25.1.3 딕셔너리에서 키의 값 수정하기

update 메서드를 사용하면 값을 수정할 수 있다. update(키=값)으로 값을 수정한다. 키는 큰따옴표나 작은따옴표는 빼고 쓴다.

만약 딕셔너리에 키-값 쌍이 없으면 추가한다.

콤마로 구분하여 키-값 쌍 여러 값을 한번에 수정할 수 있다.

update(키=값)은 키가 문자열일 때만 사용할 수 있다. 키가 숫자일 경우 update()괄호 안에 딕셔너리를 넣어서 수정할 수 있다.

[[키,값], [키,값]]처럼 키와 값을 리스트나 튜플로 수정할 수 있다.

키 리스트와 값 리스트를 묶은 zip객체로도 값을 수정할 수 있다.

Unit 23. 2차원 리스트 사용하기

2차원 리스트는 평면 구조 이다. 다음과 같이 가로x세로 형태로 이루어져 있으며, 행(row)과 열(column) 모두 0부터 시작한다.

 

23.1 2차원 리스트를 만들고 요소에 접근하기 

2차원 리스트는 리스트 안에 리스트를 넣어서 만들 수 있다. 안쪽의 각 리스트는 콤마로 구분한다. 

  • 리스트 = [[값, 값], [값, 값], [값, 값]]

리스트는 가로와 세로를 쉽게 알아내기 위해 다음과 같이 여러 줄로 입력해도 된다.

 

23.1.1 2차원 리스트의 요소에 접근하기 

2차원 리스트의 요소에 접근하거나 값을 할당할 때는 리스트 뒤에 대괄호[ ]를 두 번 사용하며 각각 세로 인덱스와 가로 인덱스를 지정한다.

  • 리스트[세로인덱스][가로인덱스]

2차원 리스트도 0부터 시작하기 때문에 가로 첫번째, 세로 첫번째 요소의 인덱스는 [0][0]이다.

 

톱니형 리스트

다음 리스트 처럼 가로 크기가 불규칙한 리스트를 톱니형 리스트 라고 한다.

톱니형 리스트는 다음과 같이 append메서드를 이용해서도 생성할 수 있다.

 

2차원 튜플 

다음과 같이 튜플안에 튜플을 넣는 방식, 튜플안에 리스트를 넣는 방식, 리스트안에 튜플을 넣는 방식이 있다. 

a = ((1,2), (3,4), (5,6))
b = ([1,2], [3,4], [5,6])
c = [(1,2), (3,4), (5,6)]

튜플은 값을 변경할 수 없다는 특징이 있다. 따라서 a는 안쪽과 바깥쪽 요소 모두 변경할 수 없고, b는 안쪽 리스트만 요소를 변경할 수 있고, c는 바깥쪽 리스트만 요소를 변경할 수 있다.

 

사람이 알아보기 쉽게 출력하기

pprint 모듈의 pprint 함수를 함수를 사용하면 사각형 구조를 유지하도록 출력할 수 있다.

 

23.2 반복문으로 2차원 리스트의 요소 모두 출력하기

23.2.1 for 반복문을 한 번만 사용하기 

for 반복문을 한 번만 사용하는 방법은 다음과 같다. 

in 앞의 변수 개수는 2차원 리스트의 가로 크기와 일치해야 한다. for문에서 2차원 리스트가 가로 한 줄 씩 반복되어 안 쪽 리스트에서 요소들을 통째로 꺼내와서 반복문의 변수에 순서대로 대입한다.

 

23.2.2 for 반복문을 두 번 사용하기 

2중 for문으로 2차원 리스트를 출력하는 방법은 다음과 같다.

a = [[1,2], [3,4], [5,6]]

for i in a:
    for j in i:
        print(j, end=' ')
    print()

for i in a: 는 전체 리스트에서 가로를 한 줄씩 꺼내온다. 이후, for j in i에서 안쪽 리스트의 요소를 하나씩 꺼내온다.

 

23.2.3 for와 range 사용하기

다음과 같이 range에 세로 크기와 가로 크기를 지정해서 리스트의 요소를 인덱스로 접근할 수 있다.

a = [[1,2], [3,4], [5,6]]

for i in range(len(a)):
    for j in range(len(a[i])):
        print(a[i][j], end=' ')
    print()

len(a)로 2차원 리스트의 크기를 구하면 세로 크기(안쪽 리스트의 개수)를 구할 수 있고, len(a[i])로 안쪽 리스트 각각의 안에 있는 요소의 개수를 구할 수 있다. 따라서 a[i][j]로 리스트의 모든 요소들을 출력할 수 있다.

 

23.2.4 while 반복문을 한 번 사용하기 

다음은 while문을 사용하여 2차원 리스트의 요소를 출력한 예시이다.

a = [[1,2], [3,4], [5,6]]
i = 0

while i < len(a):
    x, y = a[i]
    print(x,y)
    i += 1

len(a)로 2차원 리스트의 크기를 구하면 이는 안쪽 리스트의 개수(세로 크기)와 같다. 인덱스를 지정하여 값을 꺼내 올 때는 안쪽 리스트의 요소 개수 만큼 변수를 지정하면 안쪽 리스트(가로)의 요소들을 한 번에 가져올 수 있다.

 

23.2.5 while 반복문을 두 번 사용하기

다음과 같이 while 반복문을 두 번 사용할 수 도 있다.

a = [[1,2], [3,4], [5,6]]
i = 0

while i < len(a):
    j = 0
    while j < len(a[i]):
        print(a[i][j], end=' ')
        j += 1
    print()
    i += 1

2차원 리스트를 접근할 때는 리스트[세로인덱스][가로인덱스]의 형식으로 접근하기 때문에 while i < len(a): 로 세로 크기만큼 반복하고, while j in len(a[i]): 로 가로 크기 만큼 반복한다. while문으로 요소들을 가져왔기 때문에 각 인덱스는 +1 증가 시켜야 한다.

 

23.3 반복문으로 리스트 만들기

23.3.1 for 반복문으로 1차원 만들기

다음과 같이 for 반복문으로 반복하면서 append()로 요소를 추가하면 1차원 리스트를 만들 수 있다.

a = []

for i in range(10):
    a.append(0)

print(a)

 

23.3.2 for 반복문으로 2차원 리스트 만들기

for 반복문을 사용하여 2차원 리스트를 만드는 방법은 다음과 같다.

a = []

for i in range(3):
    line = []
    for j in range(2):
        line.append(0)
    a.append(line)    

print(a)

세로의 크기만큼 반복하며 안쪽 리스트로 사용할 빈 리스트를 만들어야한다. 그리고 가로의 크기만큼 반복하면서 안쪽 리스트에 요소를 추가하면 된다. 리스트에 요소를 추가하는 것은 append()로 추가할 수 있다.

 

23.3.3 리스트 표현식으로 2차원 리스트 만들기

다음과 같이 리스트 표현식을 사용해서도 2차원 배열을 만들 수 있다.

[0 for j in range(2)] 로 [0,0] 을 만들고 이것을 3번 반복하여 위와 같은 배열을 만든다.

다음과 같이 식 부분에서 [0]리스트 자체를 곱해주면 for 반복문을 한 번만 사용할 수 있다.

 

23.3.4 톱니형 리스트 만들기

다음과 같이 가로의 크기를 알고 있다고 가정한 상태에서 톱니형 리스트를 만들 수 있다.

a = [3,1,5,2]
b = []

for i in a:
    line = []
    for j in range(i):
        line.append(0)
    b.append(line)

print(b)

가로 크기를 저장한 리스트 a를 for문으로 반복하여 가로 크기를 꺼내서 각 가로 크기만큼  0을 빈 리스트에 넣고, 이 리스트를 다시 b에 넣는다. 이것도 다음과 같이 리스트 표현식을 이용해 간단하게 만들 수 있다.

가로 크기가 들어있는 리스트 [3,1,2,3,5]에서 꺼낸 숫자만큼 [0]을 곱해서 톱니형 리스트를 만들 수 있다.

 

sorted로 2차원 리스트 정렬하기

sorted(반복가능한객체, key=정렬함수, reverse=True 또는 False)의 형식으로 정렬 할 수 있다.

key에 정렬 함수를 지정하여 안쪽 리스트의 요소를 기준으로 정렬했다. student[1]은 안쪽 리스트의 1번 인덱스를 의미하며, student[2]는 안쪽 리스트의 2번 인덱스를 의미한다. 정렬 함수는 람다 표현식을 이용했다.

 

23.4 2차원 리스트의 할당과 복사 

2차원 리스트를 리스트를 다른 변수에 저장해도 같은 객체이기 때문에 요소를 변경하면 두 리스트에 모두 반영된다.

2차원 리스트는 copy를 사용해 복사해도 한 리스트의 요소를 변경하면 두 리스트에 모두 적용된다.

2차원 리스트 이상의 다차원 리스트는 완전히 복사하려면 copy메서드 대신 copy모듈의 deepcopy함수를 사용해야 한다.

copy.deepcopy()는 중첩된 리스트(튜플)에 들어있는 모든 리스트(튜플)을 복사하는 깊은 복사를 해준다.

 

23.5 퀴즈

정답은 b이다. 

정답은 d이다.

정답은 d이다.

정답은 b이다.

정답은 a,c이다.

 

23.6 연습문제: 3차원 리스트 만들기

정답은 다음 코드와 같다.

[[[for col in range(3)] for row in range(4)] for depth in range (2)]

3차원 리스트는 다음과 같이 높이x가로x세로 의 형태로 되어 있다.

리스트[높이인덱스][세로인덱스][가로인덱스]

 

23.7 심사문제: 지뢰찾기

정답은 다음 코드와 같다.

col, row = map(int, input().split())

matrix = []
cnt = 0

for i in range(row):
    matrix.append(list(input()))

for i in range(len(matrix)):
    for j in range(len(matrix[i])):
        cnt = 0
        if(matrix[i][j] == '.'):
            if i == 0 and j == 0:
                if matrix[i+1][j] == '*':
                    cnt += 1
                if matrix[i][j+1] == '*':
                    cnt += 1
                if matrix[i+1][j+1] == '*':
                    cnt += 1
            elif i == 0 and j == col-1:
                if matrix[i][j-1] == '*':
                    cnt += 1
                if matrix[i+1][j] == '*':
                    cnt += 1
                if matrix[i+1][j-1] == '*':
                    cnt += 1
            elif i == row-1 and j == 0:
                if matrix[i][j+1] == '*':
                    cnt += 1
                if matrix[i-1][j] == '*':
                    cnt += 1
                if matrix[i-1][j+1] == '*':
                    cnt += 1
            elif i == row-1 and j == col-1:
                if matrix[i-1][j] == '*':
                    cnt += 1
                if matrix[i][j-1] == '*':
                    cnt += 1
                if matrix[i-1][j-1] == '*':
                    cnt += 1
            elif i == 0 and 0 < j < col-1:
                if matrix[i+1][j] == '*':
                    cnt += 1
                if matrix[i][j+1] == '*':
                    cnt += 1
                if matrix[i][j-1] == '*':
                    cnt += 1
                if matrix[i+1][j-1] == '*':
                    cnt += 1
                if matrix[i+1][j+1] == '*':
                    cnt += 1
            elif 0 < i < row-1 and j == 0:
                if matrix[i+1][j] == '*':
                    cnt += 1
                if matrix[i-1][j] == '*':
                    cnt += 1
                if matrix[i][j+1] == '*':
                    cnt += 1
                if matrix[i-1][j+1] == '*':
                    cnt += 1
                if matrix[i+1][j+1] == '*':
                    cnt += 1
            elif 0 < i < row-1  and 0 < j < col-1:  ### 여기 조건까지
                if matrix[i+1][j] == '*':
                    cnt += 1
                if matrix[i][j-1] == '*':
                    cnt += 1
                if matrix[i-1][j] == '*':
                    cnt += 1
                if matrix[i][j+1] == '*':
                    cnt += 1
                if matrix[i-1][j-1] == '*':
                    cnt += 1
                if matrix[i-1][j+1] == '*':
                    cnt += 1
                if matrix[i+1][j+1] == '*':
                    cnt += 1
                if matrix[i+1][j-1] == '*':
                    cnt += 1
            elif 0 < i < row-1 and j == col-1:
                if matrix[i+1][j] == '*':
                    cnt += 1
                if matrix[i][j-1] == '*':
                    cnt += 1
                if matrix[i-1][j] == '*':
                    cnt += 1
                if matrix[i+1][j-1] == '*':
                    cnt += 1
                if matrix[i-1][j-1] == '*':
                    cnt += 1
            elif i == row-1 and 0 < j < col-1:
                if matrix[i][j-1] == '*':
                    cnt += 1
                if matrix[i-1][j] == '*':
                    cnt += 1
                if matrix[i][j+1] == '*':
                    cnt += 1
                if matrix[i-1][j+1] == '*':
                    cnt += 1
                if matrix[i-1][j-1] == '*':
                    cnt += 1

            print(cnt, end='')
        else:
            print(matrix[i][j], end='')
    print()

지뢰찾기 구간을 9개로 나눠서 각 경우의 수에 해당하는 코드들을 다 작성했다. 더 간단하고 효율적으로 작성할 수 있는 방법을 생각해봐야 겠다.

 

 

Unit 20. FizzBuzz문제

20.1 1 부터 100 까지 숫자 출력하기

for 반복문을 이용하여 다음과 같이 1부터 100까지 반복해주면 된다.

for i in range(1,101):
    print(i)

반복 되는 마지막 숫자는 끝나는 숫자보다 1 작으므로 101 을 넣어주면 된다.

 

20.2 3의 배수일 때와 5의 배수일 때 처리하기

다음 코드는 3의 배수일 때는 Fizz를, 5의 배수일 때는 Buzz를, 나머지 숫자는 숫자를 출력하는 코드이다. 

for i in range(1,101):
    if i % 3 == 0:
        print('Fizz')
    elif i % 5 == 0:
        print('Buzz')
    else:
        print(i)

3의 배수는 i를 3으로 나눴을때 나머지가 0 이며 5의 배수는 i를 5로 나눴을 때 나머지가 0이다. 이 두 경우에 해당하지 않으면 숫자를 출력한다. 

 

20.3 3과 5의 공배수 처리하기

위의 코드는 공배수일 경우 3의 배수인 Fizz가 출력된다. 3과 5의 공배수를 처리 하려면  다음 코드와 같다. 

for i in range(1,101):
    if i % 3 == 0 and i % 5 == 0:
        print('FizzBuzz')
    elif i % 3 == 0:
        print('Fizz')
    elif i % 5 == 0:
        print('Buzz')
    else:
        print(i)

and 연산으로 3의 배수와 5의 배수 동시에 만족시키는 경우를 처리해 줘야 한다. if의 조건식이 만족하면 뒤의 elif의 조건식은 검사하지 않기 때문에 공배수를 처리하는 조건식은 반드시 if에 들어가야 함을 주의해야 한다. 

 

20.4 논리 연산자를 사용하지 않고 3과 5의 공배수 처리하기 

3과 5의 최소공배수는 15이기 때문에 15의 배수도 3과 5의 공배수이다. 그래서 다음과 같이 코드를 수정하면 된다. 

for i in range(1,101):
    if i % 15 == 0:
        print('FizzBuzz')
    elif i % 3 == 0:
        print('Fizz')
    elif i % 5 == 0:
        print('Buzz')
    else:
        print(i)

결과 값은 위와 같다. 15라는 숫자는 3과 5의 최소공배수라는 의미를 담고 있는데, 이를 명확하게 들어내기 위해 20.3의 방식으로 하는것이 더 좋은 방법이긴 하다.

 

20.5 코드 단축하기

다음과 같이 코드를 단축하여 문제를 해결할 수도 있다. 

for i in range(1, 101):
    print('Fizz' * (i % 3 == 0) + 'Buzz' * (i % 5 == 0) or i)

결과값은 위의 값들과 같다. 

위 예시와 같이 문자열에 False를 곱하면 아무것도 출력되지 않고, 문자열에 True를 곱하면 문자열이 그대로 출력된다. 또한 or 연산은 둘다 참이면 앞의 것을 출력하기 때문에 3의 배수 이면 Fizz를, 5의 배수이면 Buzz를, 3과 5의 공배수면 FizzBuzz를, 모두 아니면 숫자를 출력하게 된다.

 

20.6 퀴즈

정답은 d이다. 

정답은 d,e 이다. 

 

20.7 연습문제: 2와 11의 배수, 공배수 처리하기

정답은 다음과 닽다.

1. i % 2 == 0 and i % 11 == 0

2. i % 2 == 0

3. i % 11 == 0

 

20.8 심사문제: 5와 7의 배수, 공배수 처리하기

정답은 다음 코드와 같다.

start, stop = map(int, input().split())

for i in range(start, stop+1):
    if i % 5 == 0 and i % 7 == 0:
        print('FizzBuzz')
    elif i % 5 == 0:
        print('Fizz')
    elif i % 7 == 0:
        print('Buzz')
    else: 
        print(i)

 

Unit 21. 터틀 그래픽스로 그림 그리기

터틀은 거북이가 기어가는 모양대로 그림을 그리는 모듈이다.

 

21.1 사각형 그리기

터틀은 다음과 같이 터미널에서 실행할 수 있다.

t.shape()는 거북이의 모양을 설정하며, 아무 값도 설정하지 않으면 화살표가 나온다. 

위와 같은 명령어를 입력하면 거북이를 100픽셀 만큼 앞으로 이동시킨다. 

거북이가 오른쪽으로 이동했고, 검은 선이 그려진 것을 확인할 수  있다.

다음 코드를 입력하면 거북이의 방향을 오른쪽으로 90도 회전시킨다. 각도에 다른 숫자를 지정하면 해당 각도 만큼 방향이 바뀐다.

이렇게 앞으로 100픽셀 가고, 거북이의 방향을 바꾸는 행위를 계속 하며 거북이를 조종하여 사각형을 그릴 수 있다.

앞으로 이동, 오른쪽으로 회전 외에도 뒤로이동, 왼쪽으로 회전 등도 가능하며 다음과 같이 코드를 줄여 쓸 수도 있다.

  • 앞으로 이동: forward, fd
  • 뒤로 이동: backward, bk, back
  • 왼쪽으로 회전: left, lt
  • 오른쪽으로 회전: right, rt

위에 그린 사각형을 fd와 rt를 이용하여 작성한 코드는 다음과 같다.

import turtle as t
 
t.shape('turtle')
 
t.fd(100)
t.rt(90)
t.fd(100)
t.rt(90)
t.fd(100)
t.rt(90)
t.fd(100)

 

스크립트 파일을 실행시 터틀 창이 바로 사라지는 경우가 생긴다면 다음 코드를 스크립트 파일 마지막 부분에 추가하면 된다.

t.mainloop()

 

21.2 다각형 그리기

다음과 같이 반복문을 사용하여 사각형을 그릴 수도 있다.

import turtle as t

t.shape('turtle')

for i in range(4):
    t.forward(100)
    t.right(90)

t.mainloop()

결과물이 나오자마자 바로 사라졌기 때문에 mainloop를 추가하였다. 

 

21.1.1 오각형 그리기

다각형에서 외각의 합은 항상 360도이기 때문에 하나의 외각은 360을 5로 나누면 된다. 소스코드는 다음과 같다.

import turtle as t

t.shape('turtle')

for i in range(5):
    t.forward(100)
    t.right(360 / 5)

t.mainloop()

오각형이기 때문에 5번 반복 하였다. 

 

21.1.2 다각형 그리기

다음과 같이 사용자로부터 입력을 받아 해당 숫자에 해당하는 다각형을 그릴 수 있다.

import turtle as t

n = int(input())
t.shape('turtle')

for i in range(n):
    t.forward(100)
    t.right(360 / n)

t.mainloop()

위는 6을 입력하여 육각형을 그린 예시이다. 

 

21.2.3 다각형에 색칠하기

다음은 빨간색으로 색칠된 육각형을 그리는 코드이다. 

import turtle as t

t.shape('turtle')
t.color('red')
t.begin_fill()

for i in range(6):
    t.forward(100)
    t.right(360 / 6)
t.end_fill()

t.mainloop()

t.color()로 펜의 색을 지정하고, 도형을 그리기 전에 t.begin_fill()로 색칠할 준비를 한다. 도형이 그려진 후에는 t.end_fill()을 이용하여 도형 전체에 펜 색이 칠해진다.

 

21.3 복잡한 도형 그리기 

터틀에서 원을 그릴 때는 circle() 함수를 사용하면 된다. 괄호 안에는 반지름의 길이가 들어간다.

 

21.3.1 원을 반복해서 그리기

다음은 for을 사용해서 원을 반복해서 그리는 코드이다. 

import turtle as t

n = 60
t.shape('turtle')
t.speed('fastest')
for i in range(n):
    t.circle(120)
    t.right(360 / n)
t.mainloop()

speed()는 거북이의 속도를 설정할 수 있다. 속도는 다음과 같이 문자열이나 숫자로 설정할 수 있다. 숫자는 0.5에서 10 까지 설정할 수 있다.

  • 'fastest' : 0
  • 'fast' : 10
  • 'normal' : 6
  • 'slow' : 3
  • 'slowest' : 1

 

21.3.2 선으로 복잡한 무늬 그리기

import turtle as t

t.shape('turtle')
t.speed('fastest')
for i in range(300):
    t.forward(i)
    t.right(91)
t.mainloop()

반복문으로 선의 길이가 0 부터 299까지 점점 길어지게 반복되고, 91도씩 회전하면서 미세하게 틀어진 사각형이 그려지면서 바깥쪽으로 퍼져나간다. 

터틀의 모양으로 설정할 수 있는 것은  'arrow', 'turtle', 'circle', 'square', 'triangle', 'classic' 등이 있다. 

 

21.4 퀴즈 

정답은 d 이다. lt는 왼쪽으로 회전하는 것이다.

정답은 d이다.

 

21.5 연습문제: 오각별 그리기

    t.forward(100)
    t.right(72*2)
    t.forward(100)
    t.left(72)

문제 설명을 따라서 코드를 작성하면 문제를 해결할 수 있다.

 

21.6 심사문제: 별 그리기

정답은 다음 코드와 같다. 

for i in range(n):
    t.fd(line)
    t.rt((360/n)*2)
    t.fd(line)
    t.lt(360/n)

 

Unit 22. 리스트와 튜플 응용하기

22.1 리스트 조작하기

22.1.1 리스트에 요소 추가하기

리스트에 요소를 추가하는 메서드는 다음 3가지가 있다.

  • append: 요소 하나를 추가
  • extend: 리스트를 연결하여 확장
  • insert: 특정 인덱스에 요소 추가

22.1.2 리스트에 요소 추가하기 

append(요소)는 리스트에 요소 하나를 추가한다. 

위 코드들을 보면 리스트에 50이라는 요소가 추가된 것을 확인할 수 있다. 또한 다음과 같이 빈 리스트에도 값을 추가할 수 있다.

 

22.1.3 리스트 안에 리스트 추가하기

append()안에 리스트를 넣으면 리스트 안에 리스트가 들어가는 중첩리스트가 된다. append()로 추가된 요소들의 길이는 항상 1이다.

 

22.1.4 리스트 확장하기 

리스트에 요소를 여러 개 추가할 때는 extend()를 사용한다. extend() 안에는 리스트가 들어가며 그 리스트의 요소들이 추가된다.

extend를 사용하면 리스트의 길이는 extend에 전달된 리스트의 길이만큼 증가한다. extend에 전달된 리스트의 요소들을 반복하면서 각 요소들을 리스트 a에 추가하는 것이다.

 

22.1.5 리스트의 특정 인덱스에 요소 추가하기

원하는 위치에 요소를 추가하고 싶을 때는 insert()를 사용한다. insert(인덱스, 요소)의 형식으로 사용하며 특정 인덱스에 요소 하나를 추가한다. 

a의 2번 인덱스에 200이 추가된 것을 확인할 수 있다.

insert()에서 자주 사용되는 패턴은 다음 두 가지 이다.

  • insert(0, 요소): 리스트의 맨 처음에 요소를 추가
  • insert(len(리스트), 요소): 리스트 끝에 요소를 추가

len(리스트)는 마지막 인덱스보다 1 크기 때문에 리스트의 마지막에 값이 추가된다. 

insert()에 리스트를 넣으면 리스트 안에 리스트가 들어가는 중첩 리스트의 형태가 된다. 

리스트 중간에 요소를 여러개 추가하려면 슬라이스를 이용하면 된다. 다음과 같이 시작 인덱스와 끝 인덱스 같게 하면 해당 인덱스의 요소를 덮어쓰지 않고도, 요소 여러개를 중간에 추가할 수 있다.

 

22.1.6 리스트에서 요소 삭제하기 

리스트에서 요소를 삭제하는 방법은 다음 두 가지가 있다. 

  • pop : 마지막 요소 또는 특정 인덱스의 요소를 삭제
  • remove : 특정 값을 찾아서 삭제

 

22.1.7 리스트에서 특정 인덱스의 요소를 삭제하기

pop()은 리스트의 마지막 요소를 삭제한 뒤 삭제한 요소를 반환한다.

pop() 괄호 안에 원하는 인덱스를 지정하면 그 인덱스에 해당하는 요소를 삭제한 뒤 반환한다. pop()대신 del 을 사용해도 상관 없다.

 

22.1.8 리스트에서 특정 값을 찾아서 삭제하기

리스트에서 원하는 값을 찾아서 삭제할 때는 remove()를 사용한다. remove(값)은 특정 값을 찾아서 삭제한다. 

리스트에 같은 값이 여러개 있을 경우 처음 찾은 값만 삭제한다.

 

리스트로 스택과 큐 만들기

append와 pop호출 형태를 90도로 돌려서 세로로 만들면 스택이되고, pop()대신 pop(0)을 사용하면 큐가 된다. 파이썬에서 스택은 리스트로 사용해도 되지만, 큐는 더 효율적으로 사용할 수 있도록 덱(deque, Double Ended QUEue)이라는 자료형을 제공한다. 덱은 양쪽 끝에서 추가, 삭제가 가능한 자료 구조이다.

collections 모듈에서 deque를 가져와야 한다. append()는 덱의 오른쪽에 요소를 추가하고, popleft()는 덱의 왼쪽 요소를 삭제한다. appendleft()로 덱의 왼쪽에 요소를 추가할 수도 있고, pop()로 덱의 오른쪽 요소를 삭제할 수도 있다. 

 

22.1.9 리스트에서 특정 값의 인덱스 구하기

index(값)은 리스트에서 특정 값의 인덱스를 구한다. 같은 값이 여러개일 경우 가장 처음 찾은 값의 인덱스를 반환한다. 

 

22.1.10 특정 값의 개수 구하기

count(값)으로 리스트 안의 특정 값의 개수를 구할 수 있다. 

a에는 2가 4개 들어 있어 4가 반환되었다.

 

22.1.11 리스트의 순서를 뒤집기

reverse()는 리스트 내 요소의 순서를 반대로 뒤집는다.

 

22.1.12 리스트의 요소를 정리하기

sort()는 리스트의 요소를 오름차순으로 정렬한다. sort(reverse=True)는 리스트의 요소를 내림차순으로 정렬한다.

리스트의 요소를 정렬하는 함수는 sorted()도 있다. sort()는 사용한 리스트를 변형시키지만, sorted()는 새로운 리스트를 생성하여 정렬한다.

 

22.1.13 리스트의 모든 요소를 삭제하기

clear()은 리스트의 모든 요소를 삭제하여 빈 리스트를 만든다.

del a[:]과 같이 시작리스트와 끝 리스트를 모두 생략하여 del로도 모든 요소를 삭제할 수 있다.

 

22.1.14 리스트를 슬라이스로 조작하기

메서드를 사용하지 않고, 슬라이스로 조작할 수도 있다. 

위 코드는 슬라이스를 사용하여 리스트 끝에 값을 하나 추가했다. len(a)는 리스트의 마지막 인덱스 보다 1 크기 때문에 리스트 끝에 값을 추가할 수 있다. 이때는 인덱스의 범위를 벗어난 리스트를 사용할 수 있다.

리스트 끝에는 여러개의 요소를 추가할 수 도 있다.

리스트가 비어있는지 확인하려면 len으로 확인할 수 도 있지만 리스트를 바로 if 조건문으로 판단이 가능하다.

if not seq:    # 리스트가 비어 있으면 True
if seq:        # 리스트에 내용이 있으면 True

리스트 인덱스에서 -1은 리스트의 마지막 인덱스를 의마한다. 리스트가 비어있을 경우 -1 인덱스를 지정하면 에러를 발생한다.

 

22.2 리스트의 할당과 복사 알아보기

다음과 같이 리스트를 만든 후 다른 변수에 할당하면 리스트는 두개가 아니라 다음과 같은 형태인 하나의 리스트가 있는것이다.

a 와 b를 is d연산자로 비교해보면 같은 True가 나온다. 변수 이름만 다를 뿐 같은 객체인 것이다.

두 변수 중 하나의 리스트에 적용되어도 같은 객체이기 때문에 두 변수 모두 반영된다.

a 와 b를 완전히 다른 두 객체로 만들려면 copy 메서드로 복사해야 한다. copy 메서드로 복사한 두 리스트는 is 연산자로 비교시 False로 나오며, == 연산자로 비교하면 요소가 모두 같기 때문에 True로 나온다. 둘 중 리스트 하나의 값을 변경해도 다른 리스트에 반영되지 않는다.

 

22.3 반복문으로 리스트의 요소를 모두 출력하기

22.3.1 for 반복문으로 요소 출력하기

for 반복문은 다음과 같이 in 뒤에 리스트를 지정하면 된다. 

for i in a: 는 리스트 a 에서 순서대로 요소를 꺼내 i에 저장하는 것을 반복한다. in 뒤에 변수가 아닌 리스트를 직접 지정할 수도 있다.

 

22.3.2 인덱스와 요소를 함께 출력하기

for 반복문에서 요소를 출력할 때 인덱스도 함께 출력하려면 enumerate를 사용한다. 

enumerate()에 리스트를 넣으면 인덱스와 요소를 동시에 꺼내올 수 있다. 

다음과 같이 start를 지정하여 시작할 인덱스의 숫자를 지정할 수 있다.

enumerate(a, start=1)은 enumerate(a, 1)처럼 간소화 시켜 사용할 수 있다. 

 

22.3.3 while 반복문으로 요소 출력하기

인덱스를 설정할때는 i <  len(a)로 리스트 길이는 마지막 인덱스 보다 1 크기 때문에 더 작게 해야 한다. 만약 <= 연산자를 사용할 경우 리스트의 범위를 벗어나 에러를 출력하게 된다.

 

22.4 리스트의 가장 작은 수, 큰 수 구하기

다음에 나오는 방식들은 튜플에서도 사용 가능하다.

 

22.4.1 가장 작은 수와 가장 큰 수 구하기

반복문을 이용하여 리스트에서 가장 작은 수를 구하는 방법은 다음과 같다.

리스트의 첫 번째 요소를 변수(smallest)에 저장하고, for 반복문으로 리스트의 요소를 바꾸며 smallest보다 작으면 smallest에 i 를 할당한다. 
가장 큰 수를 구하려면 다음과 같이 부등호를 반대로 바꾸면 된다.

리스트를 정렬하는 sort 메서드를 이용하여 구할 수도 있다. 오름차순으로 정렬하면 첫번째 요소가 가장 작은 숫자이고, 내림 차순으로 정렬하면 첫번째 요소가 가장 큰 숫자이다. 

파이썬에서 제공하는 min, max 함수를 사용해서도 구할 수 있다.

min은 가장 작은 값을 구하고, max는 가장 큰 값을 구한다. 

 

22.4.2 요소의 합계 구하기 

리스트 요소의 전체 합계를 구할 때는 다음과 같이 반복문을 사용할 수 있다.

합계를 구하는 sum 함수도 제공한다.

min,max,sum은 리스트 뿐 아니라 모든 반복 가능한 객체들(튜플, 딕셔너리, range, 세트 등)에 사용할 수 있다.

 

22.5 리스트 표현식 사용하기

파이썬은 리스트 안에 for 반복문이나 if 조건문을 넣을 수 있다. 리스트 안에 식, for문, if문 등을 지정하여 리스트를 생성하는 것을 리스트 컴프리헨션(list comprehension)이라고 하며 여기서는 리스트 표현식이라 한다. 

리스트 표현식은 다음과 같은 형태로 사용한다.

  • [식 for 변수 in 리스트]
  • list(식 for 변수 in 리스트]

range로 0 부터 9까지 i를 이용하여 꺼내고, i를 이용하여 리스트를 만드는 것이다. 

다음과 같이 i를 다른 값과 연산하면 각 연산의 결과를 리스트로 생성한다.

 

22.5.1 리스트 표현식에서 if 조건문 사용하기

if 조건문은 다음과 같이 for 반복문 뒤에 지정한다. 

  • [식 for 변수 in 리스트 if 조건식]
  • list(식 for 변수 in 리스트 if 조건식)

반복문 뒤에 if 조건문을 지정하면 숫자를 생성한 뒤 if 조건문에서 특정 숫자만 뽑아 내어 리스트를 생성한다. 위 코드의 경우에는 range로 생성한 0~9까지의 숫자들 중 짝수를 리스트에 넣었다.

if 조건문을 사용할 때도 i를 다른 값과 연산하여 리스트를 만들어도 된다.

 

22.5.2 for 반복문과 if 조건문 여러 번 사용하기

다음과 같이 for과 if를 여러 번 사용할 수 있다.

[식 for 변수1 in 리스트1 if 조건식1	for 변수2 in 리스트2 if 조건식2	...	for 변수n in 리스트n if 조건식n]
list(식 for 변수1 in 리스트1 if 조건식1	for 변수2 in 리스트2 if 조건식2	...	for 변수n in 리스트n if 조건식n)

다음은 2단부터 9단까지 구구단 리스트를 생성하는 코드이다.

다음과 같이 코드를 여러 줄로 입력하고, 들여쓰기를 하는 것도 가능하다. 들여쓰기는 안해도 되지만 가독성을 위해 하는 것이 좋다.

리스트에 for문이 여러개 일때는 뒤에서 부터 처리한다. 

 

22.6 리스트에 map 사용하기

map은 리스트의 요소를 지정된 함수로 처리하는 함수이다. 이때 원본 리스트를 변경하지 않고 새 리스트를 생성한다. 튜플에도 사용 가능하다.

다음과 같이 실수가 담긴 모든 리스트를 정수로 변환하는 코드는 map을 이용하면 더 간결하고 편하게 작성할 수 있다.

리스트의 모든 요소를 int를 사용해서 정수로 변환하고, list함수를 이용해 다시 리스트를 만들어 준 것이다. 

map은 리스트 뿐 아니라 모든 반복 가능한 객체를 넣을 수 있다. 다음 코드는 range로 생성된 정수들을 문자열로 변환한 것이다. 

 

22.6.1 input().split()과 map

input().split()의 결과는 리스트 인것을 확인할 수 있다.

map을 사용하여 정수로 입력받으면 결과는 다음과 같다.

map로 입력받으면 map object로 저장된다. 안에 들어있는 값을 보기 위해서는 리스트 함수를 이용해 리스트로 만들어 줘야 한다. 

이 리스트를 변수 두 개에 저장하면 지금까지 여러개의 변수를 입력 받을 때 저장했던 방식이다.

map 이 반환하는 맵 객체(map object)는 이터레이터 변수라서 변수 여러개에 저장하는 언패킹이 가능하다. 그래서 다음 코드 처럼 list()를 생략 한 것이다. 

a, b = map(int, input().split())

이를 풀어서 쓰면 다음과 같다.

x = input().split()	# 문자열 리스트
m = map(int, x)		# 리스트의 요소를 정수로 형변환, 맵 객체
a, b = m			# 맵 객체는 여러 변수에 저장 가능

 

22.7 튜플 응용하기

튜플은 리스트와 달리 내용을 변경할 수 없기 때문에 내용을 변경하는 메서드는 사용할 수 없고, 요소 정보를 구하는 메서드만 사용할 수 있다.

 

22.7.1 튜플에서 특정 값의 인덱스 구하기

index(값)을 활용하면 된다. 같은 값의 요소가 여러개일 경우 처음 찾은 값의 인덱스를 반환한다. 

 

22.7.2 특정 값의 개수 구하기

count(값)으로 튜플에서 특정 값의 개수를 구할 수 있다. 

a 리스트에는 2가 3개 들어 있기 때문데 3을 반환한다.

 

22.7.3 for 반복문으로 요소 출력하기

방법은 리스트와 동일하다.

 

22.7.4 튜플 표현식 사용하기

다음과 같은 방식으로 사용한다.

tuple(식 for 변수 in 리스트 if 조건식)

다음과 같이 괄호 안에 표현식을 넣으면 튜플이 아니라 제너레이터 표현식이 된다.

 

22.7.5 tuple에 map 사용하기

튜플에 map사용도 리스트와 동일하다.

위 코드는 튜플 자체를 변화시킨 것이 아니라 , 각 요소들을 int로 매핑시켜 새로운 튜플을 만들어 준 것이다. 

이 과정을 코드로 작성하면 다음과 같을것 같다.

 

22.7.6 튜플에서 가장 작은 수, 가장 큰 수, 합계 구하기

min()으로 가장 작은 수를, max()로 가장 큰 수를, sum()으로 합계를 구할 수  있다.

 

22.8 퀴즈

정답은 a,d이다.

정답은 e이다.

정답은 a,d,e이다.

정답은 b이다. 튜플은 값의 변형이 불가능하다.

정답은 d 이다.

정답은 c이다.

 

22.9 연습문제 : 리스트에서 특정 요소만 뽑아내기 

정답은 다음 코드와 같다.

[i for i in a if len(i) == 5]

리스트 표현식에 for문을 사용하여 리스트 요소들을 각각 가져와서 len()함수로 길이를 검사하고, 길이가 5이면 b리스트에 저장한다.

 

22.10 심사문제: 2의 거듭제곱 리스트 생성하기

정답은 다음 코드와 같다.

n1, n2 = map(int, input().split())

li = [2**i for i in range(n1, n2+1)]

del li[1]
del li[-2]

print(li)

리스트 li에 표현식을 첫번째 입력 값부터 두번째 입력 값(포함) 까지 2의 거듭제곱을 저장하였다. 두번째 요소와 뒤에서 두번째 요소는 del을 이용하여 1번 인덱스와 -2번 인덱스를 삭제하고 리스트를 출력하였다.

+ Recent posts