-Summary-
2차원 list, str 메서드, dictionary 메서드, set
01-27 (Unit 23.1~ Unit 23.7)
-2차원 리스트-
전에 리스트를 배웠었는데, 그때 배운 리스트는 한 줄로 늘어서는 1차원 리스트였다. 2차원 리스트는 예전에 배운 리스트와는 다르게 행, 열로 이루어져 있는 리스트다.
1차원 리스트와 똑같이 인덱스는 0번부터 시작한다.
2차원 리스트 생성 방법은 1차원 리스트와 비슷한데 <변수명> = [[<넣을 값들>],[<넣을 값들>]] 이런식으로 선언하면 된다.
위는 a라는 2차원 리스트를 생성하고 인덱스로 값을 확인하는 모습이다. a[0]을 하니 a의 0번째에 있는 요소인 [1,2]가 출력되고 a[0][0]을 적으니 1이 출력된다.
위의 2차원 리스트를 그림으로 표현하면 다음과 같다. 열 0의 행 0에는 1이 열 0의 행 1에는 2가.. 이런식으로 리스트에 요소들이 위치해 있다. 이 값을 확인할때는 a[열 인덱스][행 인덱스]로 하면 된다.
-2차원 튜플
2차원 튜플도 리스트와 똑같은 구조와 비슷한 선언방식을 가진다. 튜플 안에 튜플이 들어가도 되지만, 튜플 안에 리스트도 들어갈 수 있다. 단 들어간 리스트는 값의 변경이 가능하나 튜플은 값을 변경할 수 없다는 점을 유의해야겠다.
-2차원 요소들 출력-
1차원 리스트의 요소들은 for in 등을 사용하여 쉽게 출력할 수 있었다. 2차원도 마찬가지로 for문을 통해 쉽게 출력할 수 있다.
-1
위는 for문을 한번만 사용해서 a의 요소들을 모두 출력해주는 코드다. for x,y in a 부분에서 a의 열 하나당 2개의 행 값을 x,y에 집어넣고 x y를 출력해준다.
단 이 방법을 사용할 경우 2차원 리스트의 가로 길이가 동일해야한다.(예를 들어 0번째는 [1,2]인데 1번째는 [1,2,3] 처럼 길이가 다르면 안된다는 뜻이다.) 왜냐하면 x,y를 통해 열 하나당 2개의 행 값을 가져오는데 길이가 다를 경우 모두 가져올 수 없기 때문이다.
-2
위 사진처럼 중첩 for문을 이용해서 요소들을 출력할 수 있다. 먼저 첫번째 for문에서 a의 열을 하나씩 가져오는데, 맨 처음의 경우 리스트 [1,2]가 가져와질 것이다. i에 [1,2]가 들어와 있는 상태에서 두번째 for문 조건을 보면 i의 요소들을 j에 가져오는 것을 볼 수 있다. 이를 반복해서 모든 요소들을 출력할 수 있는 것이다.
1번 방법과 달리 이 방법은 2차원 리스트의 가로 길이가 동일할 필요가 없다는 장점이 있다.
-3
range를 이용해서 인덱스 값을 지정해, 요소들을 출력하는 방법도 있다. 첫번째 for문에서 a의 길이만큼 반복을 시작해주고 2번째 for문에서 a의 i번재 열의 행 길이 만큼 반복하고, 구해진 열, 행 인덱스 값들을 이용해 출력하는 것이다.
마찬가지로 가로길이가 동일할 필요가 없다.
-4
이 방법은 조금 신기한 감이 있었다. i를 조건 비교 변수로 사용해 a의 길이만큼 while로 반복시켜주는데 이 때 a의 i번째에 해당하는 리스트를 변수 x,y에 나눠담아서 출력하는 것이다.
단 이 방법은 1번 방법과 마찬가지로 가로 길이가 동일할 경우에만 사용할 수 있다.
-5
이 방법은 3번 방법을 while로 바꿔준 것이다. 원리는 3번이랑 비슷하다.
이 역시 가로길이가 동일할 필요가 없다.
-반복문으로 1,2차원 리스트 생성-
-1차원
위는 for문으로 0~9까지의 값을 i에 넣어주고 그 값을 append 함수를 통해 앞서 선언한 리스트 a에 넣어주는 코드다.
for문을 이용한다면 빠르게 값을 넣어줄 수 있다.
-2차원
2차원은 1차원과 다르게 for문을 두번 써줘야 한다. 첫번째 for문은 열을 정해주고, 두번째 for문이 행을 정해주는 식이다. 위 코드는 0~9까지의 수를 2번씩 a에 append 해주는 코드다.
-리스트 표현식-
앞서 배운 1차원 리스트를 표현식을 이용해 생성한 것을 이번에 2차원에서 사용해 보겠다.
기본적으로 방식은 1차원 리스트와 비슷한데, 다른점은 [ ]이 하나 더 있다는 것이다. []안의 []은 행에 값을 넣어주고, 그 뒤의 for문은 열 번호를 지정해준다.
-톱니형 리스트 만들기-
톱니형 리스트란 2차원 리스트에서 행의 크기가 불규칙한 리스트를 뜻한다.
예를 들면 [[1,2],[1,2,3],[1,2,3,4]] 같이 가로의 크기가 불규칙한 것이다.
a에 행의 크기를 각각 지정해주고 그 크기를 for에서 i에 가져온다. 2차원 리스트를 만들기 위해서 임시로 리스트를 저장할 변수가 필요하므로 temp를 생성해주고 2번째 for문에서 i의 수만큼의 크기를 가진 리스트를 0을 넣어서 생성한다. 만들어진 1차원 리스트 temp를 b에 append 해주는 식으로 반복하면 톱니형 리스트가 완성된다.
-2차원 할당, 복사-
앞에서 1차원 리스트를 다루면서 배웠던 것처럼 = 방식으로 리스트를 다른 변수에 넣어준다면 둘의 객체는 같게 되어 한 객체의 요소만 변경해도 나머지가 변경된다. 이를 방지하기 위해서 copy 함수로 복사를 해줬는데, 2차원에서는 copy를 써도 다른 객체의 요소를 변경하면 나머지가 변경된다.
-deepcopy
deepcopy는 깊은 복사란 뜻이다. 2차원 이상의 리스트를 제대로 복사하기 위해서는 copy 모듈의 deepcopy를 사용해야된다.
위처럼 copy 모듈을 import하고 deepcopy를 사용한다면 제대로 복사가 되는 것을 볼 수 있다.
가로 2 세로 2크기의 2차원 리스트는 열 2, 행 2인 리스트를 만들라는 뜻이다.
b : b만 제대로 가로 2, 세로 2인 2차원 리스트를 만들어주고 있다. O
60은 열 3번째, 행 1번째에 위치해 있다. 따라서 인덱스 값은 2,0이므로 print(a[2][0])으로 출력해주면 된다.
답 : d
d : a의 열을 i로 가져오고 열에서 행을 j로 가져와 print 해준다. O
밑줄 부분이 안보이지만 아마도 흐름상 print(a[i][j], end=' ') 이 코드 위에 들어갈 코드를 고르는 것 같다.
i가 열을 나타내는 변수로 쓰이고 있으므로 i의 값을 이용해 j가 행의 인덱스를 가리키게 하게 만드는 조건인 b가 답이다.
리스트 표현식을 이용해 열, 행의 길이가 3인 2차원 리스트를 만드는 것이다.
a : [] 안의 []에서 행의 길이와 그 길이 만큼 0을 넣어주고, 그 다음에 나오는 for문에서 열의 길이를 담당해 준다. O
c : [0,0,0]를 3번 리스트에 집어 넣는 식이므로 결과가 [[0,0,0],[0,0,0],[0,0,0]이 나온다.
3차원 리스트를 리스트 표현식을 이용해 만드는 것이 목적이다.
2차원 리스트는 for가 두번 쓰이는데 이번에는 3번 쓰거나 for를 두번쓰는 대신 [0,0,0]*3 식을 넣어주면 될 것 같다.
이번 문제는 결과를 한번 보고 답을 정해야 될 것 같아서 shell에서 작성해 봤다.
a = [[[0,0,0] for j in range(4)] for i in range(2)]
지금까지 푼 문제중 가장 어려운 문제였다. 문제에 처음 풀어보는 경우 대략 두 시간은 걸린다 나와있다. 정말 그정도 시간이 걸릴만큼 문제가 어려웠다. 또한 풀어냈지만 주어진 줄 수가 21줄이라, 이 줄 수를 맞출려고 조금 꼼수를 쓴 감이 있다. 다음에 한번 꼼수없이 21줄 안으로 풀 수 있도록 최적화 시켜봐야할 것 같다. 그래도 무엇보다 힌트 없이 마침내 문제를 풀은 순간 기분이 너무나도 좋았다.
matrix = []; answer = [] #;를 이용해 2줄의 명령을 1줄로 줄었다.(꼼수..)
col, row = map(int,input().split()) #입력
for i in range(row): matrix.append(list(input())) #col,row 만큼 입력 받는 코드
for i in range(col):
for j in range(row):
tmp = 0
if matrix[i][j] == '.': #해당 인덱스가 '.'(지뢰가 아닐) 경우
if (i-1) >= 0: tmp += 1 if matrix[i-1][j]=='*' else 0 #if문을 한줄로 씀으로서 길이를 줄였다.
if (j-1) >= 0: tmp += 1 if matrix[i][j-1]=='*' else 0
if (i+1) < col : tmp += 1 if matrix[i+1][j]=='*' else 0
if (j+1) < row : tmp += 1 if matrix[i][j+1]=='*' else 0
if (i-1) >= 0 and (j-1) >= 0: tmp += 1 if matrix[i-1][j-1]=='*' else 0
if (i+1) < col and (j+1) < row: tmp += 1 if matrix[i+1][j+1]=='*' else 0
if (i+1) < col and (j-1) >= 0 : tmp += 1 if matrix[i+1][j-1]=='*' else 0
if (i-1) >= 0 and (j+1) < row : tmp += 1 if matrix[i-1][j+1]=='*' else 0
answer.append(tmp);
else: answer.append('*') #지뢰일 경우 * 그대로 출력
#;를 이용해 2줄의 명령을 1줄로 줄었다.(꼼수..)
count = row #row의 수 만큼 나눠서 출력하기 위해 변수 하나 생성
for i in range(len(answer)):
if i >= row : row+=count; print() #;를 이용해 2줄의 명령을 1줄로 줄었다.(꼼수..)
print(answer[i],end="")
코드가 너무 길어서 간단히 설명하도록 하겠다. 해당 인덱스가 지뢰가 아닐 경우, 해당 인덱스에 +- 1(인덱스에 벗어나는 경우는 제외) 같이 모든 경우의 인덱스를 구해서 그 인덱스가 지뢰일시 tmp +=1을 해줘서 지뢰의 수를 구했다. 만약 해당 인덱스가 지뢰면 지뢰 그대로 출력하도록 설정했다.
01-28 (Unit 24.1~ Unit 26.9)
-문자열-
-replace
replace 함수는 바꿀 문자열을 새 문자로 바꿔서 반환해주는 함수다. 기존 문자열을 변경하지는 않는다.
사용은 <문자열>.replace(<바꿀문자열>,<새문자열>)로 사용하면 된다.
위 사진처럼 바꿀 문자열 뒤에 .replace를 써주고 바꿀 문자열과 새 문자열을 각각 지정해 준다면 문자열이 바뀌어서 반환되는 것을 볼 수 있다.
-translate
translate는 변환 기준이 담긴 테이블을 참고하여 문자를 바꾼 뒤 그 결과를 반환해 준다.
테이블은 <변수명> = str.maketrans(<바꿀문자>,<새문자>)로 만들면 되고 translate 함수는 <문자열>.translate(<앞서 만든 테이블명>)을 써주면 된다.
위 사진처럼 첫줄에 변환 기준이 담긴 테이블을 생성해주고 그 테이블을 이용해 translate를 사용하면 기준에 맞게 변환해준다.
d -> h
p -> 1
r -> 2
이런식으로 변환되서 문자열 dypar는 hy1a2로 반환된다.
-split
앞서 input()에서 사용했던 함수다. split은 이름 그대로 문자열을 나눠서 리스트 형으로 반환해 주는 역할을 한다. 사용은 split 뒤의 괄호에 나눌 기준이되는 문자열을 써주면 되는데 예를들어 괄호 안에 ','를 써준다면 ','를 기준으로 문자열을 나눠주는 것이다.
위처럼 split(',')를 써주니 ','를 기준으로 d,y,p,a,r을 나눠서 리스트로 반환해주는 모습을 볼 수 있다.
-join
split이 기준 문자열을 기준으로 문자열을 자르는 역할을 했다면, join은 반대로 기준 문자열을 사이사이 넣어 문자열을 이어주는 역할을 한다. 사용은 <구분자 문자열>.join(<문자열 값이 들어있는 리스트>)로 하면된다.
위는 split으로 ','를 기준으로 잘라 a에 넣은 후 잘라진 문자열 값이 들어 있는 list a를 '-'.join으로 사이사이에 '-'를 넣어 이어주는 코드다.
-upper, lower
upper, lower 함수는 문자열을 대문자, 소문자로 바꿔주는 역할을 한다. 문자열안에 대문자 혹은 소문자가 있다면 그 문자는 그대로 유지된다.
사용방법은 문자열 뒤에 .upper 또는 .lower를 써주면 된다.
참고로 실습을 해보니 upper, lower 역시 반환만해주는 함수라 원래 문자열을 바꾸지 않는다.
-lstrip, rstrip, strip
위 3개의 함수들은 공백을 삭제해주는 함수들이다. lstrip은 아마도 left strip의 약자로 문자열의 모든 왼쪽 공백을 삭제해주고, rstrip은 lstrip과 반대로 rigt strip의 약자이며 오른쪽의 모든 공백을 삭제한다. strip은 lstrip, rstrip을 합친 역할인 양쪽 공백을 모두 삭제해준다.
위 사진처럼 lstrip은 왼쪽, rstrip은 오른쪽, strip은 양쪽 공백을 모두 삭제해서 반환해준다.
또한 위 3개의 함수는 괄호안에 아무것도 넣어주지 않다면 공백 삭제의 역할을 하지만 안에 문자열을 넣어주면 그 문자열을 삭제해준다.
위 사진처럼 각 함수에 따른 방향으로 지정한 문자열을 삭제해주는 것을 볼 수 있다.
왼쪽과 오른쪽의 기준이 궁금해서 직접 실험을 해보니, 위 사진과 같이 왼쪽과 오른쪽의 기준은 양 끝인 것 같다.
-ljust, rjust, center
위 3개의 함수들은 문자열을 원하는 위치에 정렬해주는 역할을 한다.
사용은 각 함수의 괄호 안에 정수 값을 넣는다면 그 값에 따른 위치에 정렬시켜준다.
예를 들어서 ljust(10)을 써주면 문자열을 왼쪽으로 정렬하고 길이를 10으로 만들고 남는 공간은 공백으로 채워준다.
위 사진처럼 ljust는 왼쪽, rjust는 오른쪽, center는 가운데 정렬을 해주며 남는 공간은 공백으로 채워주는 것을 볼 수 있다.
-zfill
zfill 함수는 zerofill의 약자로 괄호안에 넣은 정수형 길이에 맞춰서 남는 공간을 왼쪽부터 0으로 채워준다.
-find, rfind
find, rfind는 괄호안에 찾을 문자열을 넣어 주면 그 문자열을 찾아 인덱스를 반환해준다. 만약 문자열이 존재하지 않다면 -1을 반환해준다. find와 rfind의 차이는 find는 지정 문자열을 왼쪽부터 찾아서 처음 찾은 문자열의 인덱스를 반환해 주고, rfind는 오른쪽부터 처음 찾은 문자열의 인덱스를 반환해 준다.
-index, rindex
index, rindex도 find, rfind와 마찬가지로 문자열의 위치를 찾아 인덱스를 반환해 준다. index와 rindex의 차이도 똑같이 index는 왼쪽부터, rindex는 오른쪽 부터 찾는다. 만약 문자열이 없다면 find 함수와 다르게 에러를 발생시킨다.
-count
count는 주어진 문자열에서 특정 문자열이 몇번 나오는지 알아내주는 역할을 한다.
사용은 count(<찾을문자열>)로 한다.
'dy'가 두번 나오므로 2를 반환해주는 모습을 볼 수 있다.
-메서드 체이닝
문자열에서 사용한 함수(메서드)들은 처리한 결과를 반환해준다. 이를 이용해 문자열 함수들을 계속 연결해서 호출하는 메서드 체이닝이 가능하다.
원래대로라면 'DY'라는 문자열은 존재하지 않아 find의 리턴값은 -1이 되야하지만 그 전에 upper를 써줬기에 대문자로 변경된 상태로 find 함수를 실행해서 인덱스 0인 결과가 나오는 것을 볼 수 있다.
-서식 지정자
서식 지정자란 c언어에서 %d, %s 같이 printf에 사용했던 format과 유사한 것으로 파이썬에서는 %s % <문자열> 이런식으로 쓰인다. 이 서식 지정자 같은 경우는 예를들어 "저는 19살 입니다."라는 문장이 있을 때 여기서 '저'는 1년이 지날때마다 나이가 한살씩 많아지므로 해가 지날때 마다 19에 해당하는 부분이 바뀌어야한다. 물론 나이를 담는 변수 age를 만들어 print("저는 ",age,"살 입니다.",sep="")로 해줄 수 있지만, 서식 지정자를 사용하면 좀더 쉽고, 개인적인 생각이지만 가독성이 좋아지는 것 같다.
파이썬의 서식지정자는 c언어 포맷과 비슷하다.
%s : %string의 약자, 문자열 포맷을 나타냄
%d : %decimal의 약자, 10진수 숫자 포맷을 나타냄
%f : %fixed point의 약자로 소수점 숫자 포맷을 나타냄(6자리까지)
등등
사용은 string으로 예를 들어보면 %s % <문자열> 이렇게 쓰이는데 print에서 사용한다면, print('%s' % 'dypar')로 dypar이 출력된다.
위 사진은 위에 적은 서식 지정자들을 차례로 실습해본 모습이다. 서식 지정자를 사용해주니 해당 값이 문자열로 잘 출력되는 것을 볼 수 있다.
참고로 위처럼 변수를 이용해서 사용할 수 있다.
age = 19
print("제 나이는 %s살입니다." % age)
번외로 맨위에서 서식 지정자의 필요성을 정리할 때 "제 나이는 19살입니다."라는 문장을 예시로 했었는데, 위처럼 서식지정자를 사용한 코드를 작성하면 나이를 먹을 때 마다 나이를 관리하는 변수인 age만 바꿔준다면 변경된 나이가 적용되서 출력될 것이다.
위의 %f 실습 부분을 보면 지정된 값의 소수점 자릿수와 상관없이 무조건 6자리로 맞춰서 출력해준다.
이는 %.<소수점 자릿수>f 로 사용해준다면 간단하게 원하는대로 바꿔줄 수 있다.
위 사진처럼 .3을 %f에 넣어서 사용하니 딱 소수점 3자리만 출력해주는 것을 볼 수 있다.
위에서 배운 문자열 함수(메서드) ljust, rjust를 서식지정자로 간단하게 구현할 수 있다.
%<길이>s를 해주면 길이가 양수면 문자열에서 남는 길이는 오른쪽부터 공백으로 채워주고, 길이가 음수일 경우 남는 길이를 왼쪽부터 공백으로 채워준다.
10, -10을 지정해주니 위 사진처럼 양수냐 음수냐에 따라 오른쪽 공백, 왼쪽 공백이 생기는 것을 볼 수 있다.
서식 지정자를 이용한다면 여러개의 값도 한번에 넣어줄 수 있다.
위 사진처럼 %뒤에 괄호를 만들고 그안에 값들을 첫번째부터 차례로 ','로 구분해주며 써주면 된다.
-format 메서드
서식 지정자도 나름대로 편한 면이 있었지만 들어갈 값에따라 %s,%d등 형식을 다르게 해줘야하는 단점이 있다.
format 같은 경우 서식 지정자와 똑같은 역할을 하지만 좀더 간편하고 쉽게 써줄 수 있다는 장점이 있다.
사용은 '{<인덱스>}'.format(<값>)로 써주면 된다.
위 사진의 1행은 %d 대신 {0}을 써줘서 저는 19살입니다. 라는 문자열을 출력해준 모습이다. 여기서 {}안에 들어간 0은 인덱스 번호를 나타내는데 이 인덱스 번호는 뒤에 붙은 .format의 괄호안에 있는 값의 번호를 뜻한다. 배열과 마찬가지로 맨 처음 값부터 인덱스 번호가 0으로 시작된다.
또한 2행처럼 인덱스번호만 지정해준다면, 일일이 써줘야하는 서식 지정자와 달리 한 값을 여러번 써줄 수 있다.
위 사진처럼 여러개의 format 값을 만들어 인덱스를 지정해, 값을 사용할 수 있다.
또한 위 사진처럼 {}안의 인덱스를 생략해 줄 수 있는데, 이럴 경우 format에 들어간 값을 순서대로 넣어준다.
마치 앞서 배운 딕셔너리처럼 키값을 지정해, 키 name을 호출하는 방법도 있다.
파이썬 3.6부터는 더 간단하게 변수를 불러와서 포매팅 할 수 있다. 이럴경우 뒤에 .format를 써줄 필요없이 문자열 "앞에 f를 붙여주고 {}사이에 출력할 변수명을 적어주면 된다.
-format 문자열 정렬
서식 지정자에서 문자열을 정렬시켰던 것처럼 format에서 또한 문자열을 정렬할 수 있다.
{(인덱스):<(길이)}.format(<값>) 이렇게 사용할 수 있다. 또한 ':' 다음에 나오는 부등호 기호는 <,> 둘다 사용할 수 있으며 부등호 방향에 따라 공백으로 채울 방향이 달라진다. < 경우 왼쪽, > 경우 오른쪽
-format 숫자 개수 맞추기
정수나 실수 앞에 0을 넣어서 숫자 개수를 맞출 수 있다.
'%0<개수>d' % <숫자>로 사용하면 된다.
a : count는 특장 문자열의 개수를 구한다. X
e : index는 문자열의 왼쪽 부터 찾는다. X
lower는 소문자로 만들어 주는 함수다. 그다음에 replace로 'on'을 'ON'으로 바꿔주는데 replace까지 거치고 나면 문자가 pythON이 돼 있다. 마지막으로 ljust. ljust는 남는 길이만큼 오른쪽을 공백으로 채워주는 왼쪽 정렬 함수다. 따라서 이 과정을 거쳐 반환된 문자열은 'pythON '이므로 d번이다.
a : 'Python'은 str형이므로 %s를 써줘야한다. X
c : {1}에 해당하는 값이 없다. X
e : ','와 띄어쓰기가 안들어가 있다. X
따라서 답은 b,d다.
먼저 소수점이 4자리이므로 %4f가 있어야한다. 또한 길이가 12, 오른쪽 정렬이고 남은 공간은 공백으로 채워지므로 >12 조건도 있어야한다. 이 조건에 맞고 문법 오류가 없는 보기는 c,d 밖에 없으므로 답은 c,d다.
파일경로에서 파일명만 출력하는 것이 목적이므로 문자열 슬라이스를 이용하면 되겠다 생각할 수도 있지만, 폴더의 깊이가 달라지더라도 파일명만 출력하는 것이 목적이므로 하드코딩적인 방법으로 접근하면 안된다. 항상 파일명은 파일 경로 마지막에 위치하므로 이를 이용해서 코딩하면 될 것 같다.
path = 'C:\\Users\\dojang\\AppData\\Local\\Programs\\Python\\Python36-32\\python.exe'
path = path.split('\\')
fileName = path[len(path)-1]
print(fileName)
먼저 spilt 함수로 \\을 기준으로 잘라준 다음, 파일명은 마지막에 존재하므로 리스트 path의 len(path)-1번째(맨 마지막)을 fileName에 넣어줬다.
입력된 문자열에서 소문자 'the'를 찾는 것이 목적이다. the는 항상 띄어쓰기를 해서 쓰이므로 split함수로 자른 후 for문 돌려서 the가 맞는지 확인하는 식으로 코딩해도 될 것같다.
string = input().split(' ')
count = 0
for i in string:
if i == 'the':
count += 1
print(count)
처음에는 위처럼 코드를 짜 제대로 된 결과가 나오지 않았다. 이유를 확인해 보니 문자열 안에 the.나 the,가 있는 경우가 있었기 때문에 제대로 집계하지 못한 것이었다.
string = input().split(' ')
count = 0
for i in string:
if i.strip(',.') == 'the':
count += 1
print(count)
이를 인지하고 앞서 배운 strip(,.)로 양쪽의 .과 ,를 지워주니 제대로 집계가 됐다.
가격들은 ;로 구분되기 때문에 split로 자르면 될 것 같고. 길이는 9, 오른쪽 정렬, 천단위 ,까지 포함해서 높은 순으로 정렬하는 것이 목적이다. 길이와 오른쪽 정렬은 {0:<9s}로 처리해주면 되고 천단위 , 표시는 format으로 처리해주면 될 것 같다.
price = list(map(int,input().split(';')))
price.sort(reverse=True)
for i in price:
print('{:>9,d}'.format(i))
먼저 list형으로 인풋 값을 ;기준 split해서 price 변수에 넣어준다. 그리고 sort 함수로 정렬을 해주는데, 이때 reverse=True 옵션을 줘야지 값이 큰 순서대로 정렬이 된다. 이제 마지막으로 for문으로 정렬된 요소들을 출력해주는데 이때 인덱스는 하나밖에 없으므로 번호를 지정해줄 필요 없이 {:, 오른쪽 정렬이고 길이 9이므로 부등호 >에 9, {:>9가 되는데 값들을 천 단위로 콤마를 찍어줘야하므로 9뒤에 ,를 넣어준다. {:>9, 마지막으로 int형이므로 d를 넣어주면 {:9>,d}로 완성이 된다.
-딕셔너리-
-setdefault
setdefault는 딕셔너리에서 키, 값으로 이루어진 쌍을 추가하는 함수다. 사용은 <변수명>.sedefault(<키>,<값>)으로 하는데 값을 지정해주지 않을 경우 none 값이 들어간다.
위처럼 setdefault 괄호안에 키, 값을 추가해주면 해당 딕셔너리에 키와 값이 제대로 들어가는 것을 확인할 수 있다.
또한 키만 넣었을 때는 None 값이 들어가는 것을 알 수 있다.
-update
update는 딕셔너리 안의 값을 수정하는 역할을 한다. 만약 수정하려는 값의 키가 문자열이라면 키 이름에서 ' '를 뺀 상태로 update(<키>=<바꿀값>)으로 수정해줄 수 있다. 또한 지정한 키가 없다면 새로운 키를 추가해서 바꿀 값을 넣어준다.
만약 키가 숫자일 경우에는 {}를 추가해서 딕셔너리를 선언하는 것 같이 update({<키>:<바꿀값>})으로 써줘야한다.
여러개의 값을 update에서 ','로 나눠서 값을 변경할 수 있다.
딕셔너리를 생성할 때 처럼 리스트와 튜플식으로 값을 수정할 수 있으며, zip 함수로 키와 값을 몰아서 수정할 수 있다.
-pop
pop은 리스트에서 썻던것과 비슷하게 딕셔너리에서는 특정 키,값을 삭제해주는 역할을 한다. 또한 삭제하고 그 키의 해당 값을 반환해준다.
pop 대신 del로 삭제 가능하다.
-popitem
popitem은 python 3.5 이하에서는 pop처럼 맨 뒤에 키와 값을 삭제하는게 아닌 임의(랜덤)로 키,값을 삭제하지만 python 3.6 이상은 pop과 마찬가지로 맨 뒤의 키와 값을 삭제하고, 삭제한 키와 값을 튜플로 반환해 준다.
-clear
clear는 딕셔너리의 모든 키, 값을 삭제하는 역할을 한다.
-get
get 명령어는 딕셔너리에서 특정 키의 값을 가져오는 역할을 한다.
-items, keys, values
items는 모든 키와 그 키의 값을 모두 가져온다.
keys는 모든 키를 가져온다.
values는 모든 값을 가져온다.
-fromkeys
fromkeys 함수는 리스트나 튜플에 담긴 값들로 딕셔너리의 키를 생성해준다. fromkeys 괄호 안에 키 리스트만 준다면 키만 정의되고 값은 None로 저장된다. 혹은 키리스트와 값을 준다면 값이 생성된 키들에 저장된다.
-반복문으로 키,값 출력
리스트, 튜플과 마찬가지로 딕셔너리도 for문을 통해 모든 키와 값을 출력해줄 수 있다.
리스트, 튜플을 출력했듯이 for i in 방식으로 출력한다면 맨 윗행의 코드처럼 키만 출력되는 것을 볼 수 있다. 키와 값을 같이 출력하려면 위에서 배운 items를 사용하면 되는데, 이때 키와 값을 담을 두개의 변수가 필요하다.
키만 출력하는 방법은 그냥 for i in a를 써줘도 되지만 위에서 배운 keys를 사용하면 키만 출력되게 할 수 있다.
또한 값의 경우도 마찬가지로 values를 써준다면 값만 출력된다.
-딕셔너리 표현식
역시 리스트, 튜플과 마찬가지로 for, if문으로 딕셔너리를 생성 가능하다.
형식은 {<키>: <값> for <키>, <값> in <변수명>} 혹은 dict({<키>: <값> for <키>, <값> in <변수명>})
리스트, 튜플 표현식보다는 좀더 많이 복잡해서 나도 이해하는데 시간이 좀 걸렸다.
keys = ['a', 'b', 'c', 'd']
x = {key: value for key, value in dict.fromkeys(keys).items()}
위 코드가 코딩도장에 나온 예시 코드다. 먼저 키 이름을 담는 리스트 keys를 선언해준다. 표현식을 보면 value in dict.fromkeys(keys).items() 이부분이 위에서 배운것처럼 키 이름을 담은 리스트를 이용해 값들이 None인 리스트를 하나 만들고 items() 함수로 리스트의 키와 값을 각각 변수 key, value에 넣어주고 이 두 값을 이용해 최종 리스트를 만드는 것이다.
솔직한 생각으로는 굳이 for를 안써도 x = dict.fromkeys (keys)로 똑같은 키와 값을 갖는 딕셔너리를 생성할 수 있는 것 같은데 표현식을 써야하는 이유는 아직까지는 잘 모르겠다.
코딩도장에서도 단순 for문을 사용하는 것은 복잡하기만 하고 fromkeys 함수를 사용한 것과 결과가 큰 차이가 없다 적혀있다. 딕셔너리의 표현식의 진가는 if문을 사용할 때 유용하게 발휘된다고 한다.
for와 if, del을 이용해서 만든 코드인데, 이 코드는 값이 1일 경우 해당 키를 삭제하는 코드다.
이론상으로 오류는 보이지 않았지만 실행해보면 딕션너리는 반복중에는 크기가 바뀔 수 없다는 오류가 뜬다.
하지만 딕셔너리 표현식을 사용한다면 오류가 뜨지 않는다.
위처럼 표현식을 사용한다면 값이 1인 키는 사라지는 것을 볼 수 있다. 위에 적은 표현식에서 if j != 1만 추가된 것 뿐인데, 차이점은 전반적인 원리는 비슷하지만 a.items()로 만들어진 딕셔너리에서 값이 1이 아닌 키와 값들만 i, j에 넣어서 새로운 딕셔너리를 생성시켜주는 것이다. 위에서는 조건을 ==으로 넣었지만 표현식에서는 !=으로 넣는 이유는 여기에는 새로운 딕셔너리를 만들 때 들어가는 값들만 조건이 참이 되게 해야하므로 !=을 넣어 1을 제외한 모든 값을 i,j로 넘겨주는 것이다.
-중첩 딕셔너리
리스트 안의 리스트인 2차원 리스트처럼 딕셔너리 또한 딕션러리 안에 딕셔너리가 존재하는 중첩 딕셔너리를 사용할 수 있다. 생성 방식은 2차원 리스트와 비슷하게 단지 딕셔너리 안의 값에 딕셔너리를 넣어주면 된다.
위처럼 중첩해서 딕셔너리를 생성할 수 있고 값을 불러올 때는 2차원 리스트처럼 [열에 해당하는 키][행에 해당하는 키]로 불러올 수 있다.
-딕셔너리의 할당과 복사
리스트와 마찬가지로 단순 = 연산자로 값을 넣어준다면 두 객체가 같게되어 한 객체의 값을 변경하면 나머지 객체에도 영향이 가게 된다. 그래서 리스트와 똑같이 copy를 사용해 복사해준다면 이 문제를 해결할 수 있다.
중첩 디렉토리 또한 2차원 리스트와 마찬가지로 copy 모듈을 import한 후 deepcopy를 사용해서 복사해야한다.
키 'Python'과 해당 값을 삭제하는 방법은 x.pop('Python') 또는 del x['Python]으로 할 수 있다. 따라서 답은 c, e다.
b : setdefault는 키만 지정하면 값은 None을 넣어준다. X
c : keys는 키를 가져온다. X
키를 출력하는 방법은 for in만 써주거나 딕셔너리 변수 뒤에 .keys()를 붙여서 for문을 사용하면 된다.
따라서 답은 b, c가 되는데 e는 items로 키와 값 둘다 가져왔지만 출력은 키만 해줬으므로 e도 해당된다.
답 : b,c,e
특정 값을 가진 키와 값을 삭제하려면 딕셔너리 표현식을 써주면 된다.
a : 저렇게 반복문으로 삭제한다면, 반복문중에는 딕셔너리의 크기를 변경할 수 없다는 오류가 뜬다. X
b : 40인 키는 없다. X
c : 이 표현식은 키와 값을 받아서 그대로 새로운 딕셔너리를 생성하는 식이다. X
d : 40인 키를 삭제하는 것이므로 != 조건식이 맞다. O
e : ==40 조건식을 써주면 값이 40인 키와 값을 제외한 모든 쌍이 삭제된다. X
중첩 딕셔너리에서 중첩 키에 접근하는 방법은 [열의 키][행의 키]로 하면 된다.
satellites가 2개가 있긴 하지만 올바르게 접근하는 것은 d밖에 없다.
답 : d
중첩 딕셔너리는 deepcopy를 해줘야만 제대로 복사가 된다. a = x, b = x.copy()는 제대로 복사가 안되므로 이 두 변수의 값은 x의 변동에 영향이 미쳐진다.
따라서 답은 c.
maria 딕셔너리에서 과목 점수의 평균을 구하는 것이 문제다.
for문을 이용해서 값을 다 더한 후 딕셔너리의 길이로 나누는 방법도 있지만, 주어진 줄이 1줄이므로 앞서 배운 리스트의 값들을 더해주는 sum 함수와 딕셔너리에서 값들만 불러오는 values 함수를 사용해서 구하면 될 것 같다.
maria = {'korean': 94, 'english': 91, 'mathematics': 89, 'science': 83}
average = sum(maria.values())/len(maria)
print(average)
딕셔너리를 만드는 부분은 보기에 주어져있다. 목표는 단지 딕셔너리에서 키가 delta인 키,값 삭제, 값이 30인 키, 값 삭제다. 반복문으로 돌린다면 오류가 뜨니 딕셔너리 표현식을 사용하면 될 것 같다.
keys = input().split()
values = map(int, input().split())
x = dict(zip(keys, values))
x = {i : j for i,j in x.items() if i != 'delta' and j != 30 }
print(x)
1,2행은 입력을 받아오는 부분, 4행은 입력 받은 키,값들을 토대로 딕셔너리를 생성한다. 5행에서 키와 값이 'delta', 30이 아닌 키와 값만 불러와서 새로운 딕셔너리를 생성한다. 그리고 x를 출력하면 키와 값이 'delta',30인 키와 값은 사라진 상태로 출력되게 된다.
-set-
set는 교집합, 합집합 같은 집합 관련 자료형이다. 만드는 법은 <변수명> = {<값>,<값>,<값>}으로 하면 된다.
또한 세트는 다른 시퀀스 자료형들과 달리 요소의 순서가 정해져 있지 않다. 코딩도장에는 순서가 정해져 있지 않기 때문에 출력할 때 매번 다른 순서로 나온다했지만, 직접 실습을 해봤을 때는 맨 처음에 넣었던 값의 순서만 랜덤으로 바뀌고 그 다음부터는 바뀐 순서대로만 출력되는 것 같다. 순서가 정해져 있지 않기 때문에 리스트나 튜플처럼 [<인덱스>]를 이용해서 요소를 불러올 수 없다.
또한 요소는 중복이 불가하다. 만약 중복된 값을 넣을 시 그 값은 하나로 처리된다 .
세트 안에 세트 또한 넣을 수 없다. 2차원 세트가 가능할줄 알았지만 2차원 세트는 불가능하다고 한다.
위 사진처럼 세트를 만들고 출력해본다면, 값이 넣은 순서가 아닌 랜덤으로 바뀌어서 출력되는 것을 볼 수 있다.
또한 인덱스 번호로 값을 불러올 수 없는 것도 알 수 있다.
-in
세트에 특정 값이 있는지 확인하는 방법은 <값> in <세트 변수명>으로 해주면 된다. 그러면 있는지 없는지 여부를 True와 False로 반환해 준다. 또한 not in도 사용 가능하다. 이는 in으로 나온 결과값의 반대로 결과가 반환된다.
-set(메서드)
set로도 세트를 생성할 수 있다. 방법은 set 괄호안에 반복 가능한 객체를 넣으면 되는데, 이 반복 가능한 객체란 문자열이나, range()같이 값이 여러개 나오는 것을 뜻하는 것 같다.
위처럼 set 괄호안에 문자열, range 같이 반복가능한 객체를 넣는다면 세트가 생성되는 것을 알 수 있다.
빈 세트는 set()만 써주면 생성된다.
-frozenset
frozenset는 set이지만 값의 변경이 불가능하게 만드는 세트다. 사용은 위의 세트와 비슷하게 set 대신 frozenset로 적어주면 된다. 그리고 frozenset는 중첩 set 구현이 가능하다 한다.
-union, |
union, |는 합집합을 구해주는 역할을 한다. 여기서 합집합이란 두 집합의 원소들을 모두 합친 집합을 뜻한다. 참고로 중복은 안된다.
사용은 위와 같이 <세트1>.union(<세트2>)이나 <세트1>|<세트2>로 해준다면 된다.
-intersection, &
intersection과 &은 교집합을 구해준다. 교집합은 두 집합에서 겹치는 부분을 말한다.
사용방법은 union, |과 같다.
-'-'
'-'는 차집합을 구해준다. 차집합은 첫번째 집합 원소들에서 두번째 집합 원소들을 빼주는 건데, 첫번째 집합과 두번째 집합 값이 겹치는것만 뺀 첫번째 집합이다.다. 예를 들어 집합 1은 1,2,3이 있고, 집합 2는 2,3,4가 있을 때 집합 1 - 집합 2 = 1가 되는 것이다. difference 함수로도 사용할 수 있다.
사용방법은 위 intersection, |,&과 같다.
-'^'
'^'는 대칭차집합을 구해준다한다. 위 '-'는 겹치는 것을 빼고 남은 첫번째 집합의 원소들만 출력해줬는데, ^는 첫번째 집합과 두번째 집합의 겹치는 것만 빼주고 나머지를 반환해준다. 예를 들어 집합 1은 1,2,3이 있고, 집합 2는 2,3,4가 있을 때 집합 1 ^ 집합 2 = 1,4가 되는 것이다.
위의 ^,&,| 등의 결과를 적용하는 방법은 간단하다. 연산자 뒤에 =을 써주면 된다. 예를 들어 a ^ b일때 a ^= b를 써준다면 a, b의 대칭차집합 결과를 a에 넣어준다.
-update, intersection_update, difference_update, symmetric_difference_update
위의 함수들은 교집합, 합집합등을 수행하고 그 결과값을 적용시켜주는 역할을한다.
update = |=
intersection_update = &=
difference_update = -=
symmetric_difference_update = ^=
간단히 update와 intersection_update만 캡처했다. 위 코드는 각각 &=, |=와 같은 결과를 내는 것을 알 수 있다.
-부분, 상위집합 확인
부분집합 : 집합 1, 집합 2가 있다 가정할때 집합 2의 원소가 모두 집합 1에 있다면 집합 2는 집합 1의 부분집합이라 한다. <=, issubset으로 구할 수 있다.
진부분집합 : 부분집합과 비슷하지만 부분집합은 집합 1의 원소와 집합 2의 원소가 모두 같을 때도 포함되는데, 진부분집합은 집합 2의 원소가 집합 1에 모두 있지만 집합 1과 집합 2가 완전히 똑같지 않은 것을 말한다. <로 구할 수 있다.
상위집합 : 부분집합의 반대 개념으로 집합 1, 집합 2가 있다 가정할때 집합 2의 원소가 모두 집합 1에 있다면 집합 1은 집합 2의 상위 집합이라 한다. >= issuperset으로 구할 수 있다.
진상위집합 : 상위집합과 비슷하고, 진부분집합의 정반대다. >로 구할 수 있다.
-==, !=, isdisjoint
==은 두 집합이 서로 같은지 확인한다. 세트는 요소의 순서가 없으므로 요소만 같다면 같다고 판단한다.
!=은 ==의 반대로 두 집합이 서로 다른지 확인한다.
isdisjoint는 두 집합이 겹치는 요소가 있는지 확인하고, 겹친다면 False, 겹치지 않다면 True를 반환한다.
-add, remove, discard, pop, clear, len
add : 세트에 요소를 추가. add(<값>)
remove : 세트에서 특정 요소 삭제, 만약 지우려는 요소가 없다면 에러 발생. remove(<값>)
discard : 세트에서 특정 요소 삭제, remove와 다르게 요소가 없다면 그냥 넘어감. discard(<값>)
pop : 앞에서 배웠던 pop과 같은 역할을 한다. 랜덤으로 요소를 삭제하고 그 요소를 반환. pop()
clear : 모든 요소 삭제. clear()
len : 세트의 요소 길이 구함. len(<세트>)
-세트의 할당, 복사
리스트, 튜플, 딕셔너리처럼 단순 =으로 복사해준다면 한 객체의 값을 변경하면 다른 객체에 영향을 미치게 된다.
이를 방지하기 위해서는 앞에서 배운 것처럼 copy를 사용하면 된다.
-반복문으로 세트 요소 출력
리스트, 튜플 등과 똑같이 for i in <세트>로 요소들을 모두 출력할 수 있다. 세트에는 요소의 순서가 없으므로 랜덤으로 출력되지만, 숫자의 경우 입력 순서대로 출력된다.
위처럼 숫자로 적었을 때는 입력 순서대로 출력되지만 문자의 경우 순서가 랜덤으로 출력된다.
-세트 표현식
리스트 표현식과 원리는 똑같다.
리스트 표현식과 똑같은 원리로 세트 a에 담아주는 것을 볼 수 있다. 다른점은 []대신 {}을 사용한다.
역시 if문을 써서 넣어줄 수도 있다. not in 'par'로 'dypar'에서 하나씩 문자를 받아온 변수 i의 값이 'par' 문자들과 같지 않는다면 넣어주는 것이다.
b : 빈 세트는 set()으로 만들 수 있다. 실제로 쉘에서 실행해보니 type이 dict로 나오는 것을 확인했다. X
b : ^는 겹치는 것만 빼서 두 집합의 요소를 반환해준다. X
e : difference는 -와 같은 역할을한다. X
b : issubset은 부분집합을 구하는 함수다. X
d : 두 세트가 같지 않을 때 참이다. X
d : 에러를 발생시키지 않는다. X
e : 지정된 요소가 아닌 임의(랜덤)요소다. X
c : symmetric....은 ^=와 같다. X
d : issuperset은 >=와 같다. X
표현식을 이용해서 {0,1,3,4,5,6,8,9}를 만들어야한다. 보면 0~9까지의 숫자인데 2와 7이 빠져있다. 2와 7이 빠져야하므로 조건은 != 2 or != 7이 되야한다. 따라서 a가 맞고 또한 c는 is not 2 and is not 7로 조건이 맞으므로 a,c가 답이다.
3과 5의 공배수를 세트형태로 출력하는 것인데, 주어진 코드를 보면 a & b로 출력하는 것을 보아 a는 3의 배수, b는 5의 배수를 구한다면 주어진 코드를 통해 a,b에 겹치는 공배수를 구해서 출력될 것이다.
a = {i for i in range(1,101) if i % 3 == 0}
b = {i for i in range(1,101) if i % 5 == 0}
print(a & b)
입력된 두 정수의 공약수를 세트 형태로 구하는 것이 목표다. 약수는 해당 수를 나눌 수 있는 수를 뜻하므로 range를 이용해 해당 수까지 모든 수를 나눠보고 나머지가 0이라면 약수 처리해주면 된다.
input1, input2 = map(int,input().split())
a = {i for i in range(1,input1+1) if input1 % i == 0}
b = {i for i in range(1,input2+1) if input2 % i == 0}
divisor = a & b
result = 0
if type(divisor) == set:
result = sum(divisor)
print(result)
range로 1~입력받은 값+1까지 범위를 정하고 이 범위 안의 모든 수를 입력 받은 값에 나눠줘서 나머지가 0이 나온다면 그 값을 set에 넣어줬다. 그리고 만들어진 두 리스트를 & 연산을 거치니 공약수가 구해진다.
'Old (2021.01 ~ 2021.12) > Programming' 카테고리의 다른 글
생활코딩 HTML 기술소개 ~ 선택 (0) | 2021.02.07 |
---|---|
파이썬 코딩도장 Unit 27 ~ 37 (0) | 2021.01.31 |
파이썬 코딩도장 Unit 20 ~ 22 (0) | 2021.01.26 |
파이썬 코딩도장 Unit 12 ~ 19 (0) | 2021.01.24 |
파이썬 코딩도장 Unit 8 ~ 11 (0) | 2021.01.21 |