Skip to content

Latest commit

 

History

History
284 lines (244 loc) · 13.1 KB

File metadata and controls

284 lines (244 loc) · 13.1 KB

[Day 2]

목차

  1. 논리연산자
  2. 조건문
  3. 다중조건문
  4. 컨테이너 자료형

논리연산자

  • AND (빡빡함)

  • OR (헐랭함) : 둘 다 False인 경우는 못 참지!

  • NOT : True ↔ False

  • 논리연산자는 비교연산자와 함께 많이 쓰임

  • python은 아래와 같이 두 가지 경우를 함께 비교할 수 있음



조건문

if-else

  • 조건을 만족하면 else에 해당하는 것은 실행되지 않음
  • 조건이 만족되지 않으면 else에 해당하는 것만 실행됨
    • 깔끔하게 모 아니면 도, 흑백논리로 떨어질 때
  • else는 굳이 조건문이 필요하지 않음 if 뒤의 조건이 아닌 경우 모두이기 때문, 그 이외의 모든 케이스

if-if

  • 어쨌든 둘 다 실행은 됨
  • 미로에서 모든 방향을 봐야하는 경우 사용
  • 사다리타기에서 가지가 겹치는 경우 사용

들여쓰기

  • 들여쓰기를 꼭 해야 함
  • 들여쓰기를 하지 않은 동작들은 조건에 상관없이 항상 실행
  • if 옆에는 비교연산, 논리연산(Boolean 값으로 표현될 수 있는 값)이 들어감
  • 문제에서 어떤 로직을 원하는지 명확하게 봐야 함
  • Python의 들여쓰기는 4space 혹은 1tab

살펴보기

  • if 오른쪽에 오는 애들이 변동을 하는지를 살펴야 함
  • print() 메서드는 디버깅용 → 어디서 잘못되었는지를 체크!
  • %2 를 하는 경우(짝수를 구하거나 홀수를 구하거나) → 2로 나누면 무조건 0 아니면 1이 되는데 0은 False, 1은 True로 표현될 수 있음
    • 이런 경우에도 ==0을 해야 할까요?
      • 처음 공부할 때는 이렇게 해도 되지만, 파이썬의 스타일 가이드에서는 not 연산자를 이용할 것을 권장 ⇒ not n % 2
      • n = 3 (홀수)인 경우,
        n % 2 는 1을 반환함, 1은 true
        짝수를 찾는 경우 n이 홀수일 때 true이면 안 되므로 not을 앞에 붙여서 Boolean으로 평가되는 값을 false로 반전시켜 줌
         a = 3
        
        if a % 2 == 0:
            print("if 통과")
        else:
            print("else 통과")
        
        if not a % 2:
            print("if 통과")
        else:
            print("else 통과")
        
        # 둘 다 else 통과가 됨
      • 비교할 때 is도 많이 사용하지만, 이것은 id값을 판별하는 것이기 때문에 무분별한 사용은 지양!
  • List는 오류를 많이 발생시키는 친구, 그러나 if 사용 시 단축평가로 오류 발생을 막을 수 있음
    • index out of range error → 접근 범위 외의 인덱스에 접근하는 경우

      a = [1, 2, 3]
      
      if len(a) < 3 and a[4] != 4:
          print("if 통과")
      else:
          print("else 통과")
      
      # 원래 a[4] != 4는 index out of range 에러가 발생하지만
      # 앞의 조건인 len(a) < 3이 false이기 때문에 단축평가로 인해 range 오류 없이 else문을 통과하게 됨
    • not을 잘 활용하면 깔끔하게 코드를 읽을 수 있음

  • ‘’’ ‘’’으로 감싼 여러 줄 주석은 주석이 아님!
    할당되지 않은 string이기 때문에 활용할 수 있는 것!
    → 권장하는 방법은 전체 줄을 긁어서 cmd + /


다중조건문

  • if문 내의 또 다른 if
    • if를 다른 if문 안에 4space만큼 들여쓰기 해서 작성
  • 위처럼 작성되는 중첩 if문을 피하기 위해 elif가 등장
    • elif가 많은 경우 순서대로 보면 됨
# 만약 변수 age가
#
# 1) 30 이상이라면 “30대입니다.”를 출력한다.
# 2) 30 미만이지만 20 이상이라면 “20대입니다.”를 출력한다.
# 3) 20 미만이라면 10 이상이라면 "10대입니다."를 출력한다.
# 4) 10 미만이라면 "응애입니다."를 출력한다.

age = 8

# if-else로 구성하기
if age >= 30:
    print("30대 입니다.")
else:
    if age >= 20:
        print("20대 입니다.")
    else:
        if age >= 10:
            print("10대 입니다.")
        else:
            print("응애입니다.")

# if-elif-else로 구성하기
if age >= 30:
    print("30대 입니다.")
elif age >= 20:
    print("20대 입니다.")
elif age >= 10:
    print("10대 입니다.")
else:
    print("응애입니다.")


컨테이너 자료형

컨테이너 자료형이란

  • 하나의 변수에 하나의 값을 담는 것이 아니라, 한꺼번에 여러가지 정보를 담고 싶을 때

순서가 있는 컨테이너

  • 리스트, 문자열, 레인지, 튜플
  • 인덱싱이 가능
  • 순서가 있다는 것과 정렬이 되는 것은 전혀 다른 개념이므로 주의

순서가 없는 컨테이너

  • 집합(set), 딕셔너리
  • 딕셔너리의 경우 논쟁의 여지가 있음
    지금은 순서가 있다고 봐도 무방하지만, 채점 프로그램의 버전이 3.7 이하인 경우 순서가 없는 컨테이너로 분류될 수 있으므로 주의하기!

리스트

  • 빈 리스트도 가능, 데이터를 순서있게 저장하는 컨테이너 자료형
  • 대괄호 []를 이용하여 생성하고 콤마 ,를 이용하여 요소간 구분
  • Python은 배열(array)을 쓰려면 따로 import해서 써야 함
    python의 list는 다양한 자료형이 저장될 수 있음
    ex) set, list, str, int ...
  • 빈 리스트는 변수 뒤에 = []으로 생성, = list()로 인스턴스를 생성하여서도 빈 리스트 생성 가능
    • 이 때 id값은 모두 분리됨
  • 길이는 맨 끝 index number + 1, len() 내장함수로 리스트의 길이를 알 수 있음

리스트 연산

  • 덧셈
    • 더할 때 원소로서 리스트가 들어오는 것이 아님
    • 내부 요소들만 합쳐주는 것
    • .append() 내장함수와 유사
  • 곱셈
    • 객체 복사가 가능함

    • 2차원 리스트에서 사용 시 약간 복잡한 문제가 발생

      • [0] * 3을 하면 요소가 3개인 1차원 리스트를 만들 수 있음
        • 이 경우 각 요소의 주소값은 일치함!
          왜?! -5~256은 사람들이 너무 숫자를 많이 써서 각 숫자들을 한 주소값에 모두 할당해 둠

          • 해당 범위를 벗어난다면 같은 Int값이더라도 다른 주소값을 가지게 됨!

          • 하지만, 아래와 같이 튜플로 선언하는 경우 인터프리터 특성 떄문에 같은 주소값을 가지게 됨

    • 2차원 리스트란?

      • 리스트 내부에 리스트를 가지고 있는 형태
        ex) matrix = [[3, 7, 9], [4, 2, 6], [8, 1, 5]]
      • 유방향 그래프, 인접 행렬로도 많이 쓰임!
        예)

인덱싱

  • 뚜껑 번호(index number)는 0부터 시작
  • 음수 인덱싱(역으로 인덱싱)도 가능, -1이 맨 끝 요소
  • Python은 Mutable(변경가능)하기 때문에 리스트 인덱스로 접근해서 수정이 가능
  • 튜플은 순서가 있음(Iterable, 반복 가능)하므로 자유도가 제한됨?!
    • list가 가변적이라고 무조건 좋은 것은 아님! 에러는 좋은 것! ⇒ 의도를 가지고 타당하게 사용하면 된다!
    • 절대로 바뀌지 않는 좌표값 등은 튜플로 설정해주면 됨, 상수값
      참조만 하게끔 사용하게 되는 값들
    • set에는 튜플은 들어갈 수 있지만 list는 들어갈 수 없음
      • 튜플은 Hashable하기 때문
    • 반복 가능, 수정 가능 ⇒ list ⇒ 그렇기 때문에 범용성이 높음!

코테를 위한 리스트 메서드 정리

  • .append()

    • return값이 없음, None으로 반환됨
  • .pop(index)

    • pop은 뽑아서 어딘가에서 사용할 의도가 명확하기 때문에 **return 값이 있음**
    • dfs 문제 같은 경우에는 이를 담아서 사용
    • 특정 index를 가져다가 뽑을 수 있음, index값을 지정하지 않는 경우 맨 뒤에서 뽑아옴
  • ⭐⭐⭐⭐ .sort() → 메서드, ****원본 자체를 정렬하게 됨

    • 작은 수부터 자례대로 정렬 가능
    • key 옵션으로 기준을 선택할 수 있음
    • sorted() → 함수, 원본은 변하지 않고 정렬된 새로운 리스트를 만듦
      • 원본과 id값을 분리함
    • sort는 기본적으로 사전식 정렬(금메달, 은메달, 동메달)
    • 2차원 리스트는 어떻게 sorting해야 할까?
      • 첫번째 요소들을 먼저 비교하여 순차적으로 정렬
      • 첫번째 요소가 겹치는 경우 두번째 요소를 확인하여 순차적으로 정렬
      • 예) 미세먼지 농도, 초미세먼지 농도, 황사 농도를 가지고 있는 2차원 리스트의 경우 우선순위를 주어서 그 기준으로 정렬
    • 문자열은 어떻게 sorting 할까?
      • sort는 문자열 sorting이 가능함
      • a, b, c를 ascii 값으로 sorting
    • 정렬 알고리즘을 외우는 것보다 sort 메서드를 열심히 파는 것이 더 좋음
      • 아무리 본인이 열심히 구현해도 C코드로 구현된 sort 메서드를 사용하는 것이 좋음
    • 역순으로 정렬하려는 경우 key 옵션과 lambda 익명 함수를 활용
      nums.sort(key=lambda x: -x)
      • 익명함수 람다는 뭘까?
        • 함수 = 박스 ⇒ input이 들어오면 output이 나가는 함수
        • 이름을 지을 필요가 없는 함수
      • 2차원 리스트의 경우 key 옵션과 lambda 익명함수로 우선순위를 지정해 줄 수도 있음
        a = [[4, 4, 15], [6, 1, 6], [0, 5, 2], [9, 1, 5]]
        a.sort(key=lambda x:(x[1], x[2]))
        print(a)
        
        # [[9, 1, 5], [6, 1, 6], [4, 4, 15], [0, 5, 2]]
        
        a.sort(key=lambda x: (-x[2], -x[0]))
        # 튜플 내부 값에 -를 붙여주면 역순으로도 가능
  • .reverse() 주어진 리스트를 반대로 뒤집음, 원본 변경

    • reversed() → 주어진 리스트를 반대로 뒤집은 새로운 리스트를 만듦
  • .instert(index, value)

    • 새치기하는 걸 구현할 수 있음
    • 해당 자리에 있는 애를 뒤로 밀고 value에 해당하는 값을 해당 자리에 넣음
  • .extend(반복 가능한 객체)

    • List는 덧셈 연산이 가능해서 굳이…? 싶을 수 있음
    • 여러 요소를 더하는 것
    • 2차원 배열에 벽 칠 때 주로 사용함!
    • 반복 가능한 객체, Iterable이 들어감
  • .count(n)

    • n이 리스트에 몇개 있는지를 반환
  • .index(n)

    • n이 위치한 index 값을 반환
    • 찾지 못하면 에러가 발생

슬라이싱

  • 피자조각 자르듯 잘라오는 것
  • ⭐⭐ id값을 원본과 분리함 [포함:미만] 으로 슬라이싱 ≤ <
  • 왼쪽을 비운다면 처음부터 오른쪽까지, 오른쪽을 비우면 왼쪽부터 끝까지
  • 그렇다면, 둘 다 비우면 어떻게 될까? [:]
    • 리스트 전체를 도려내서 카피함(얕은 복사) → id값도 분리가 됨
      • 얕은…?!
        1차원 배열에서 얕은 복사 = 깊은 복사
  • 슬라이싱은 껍데기만 벗긴 것 → 내부값을 제대로 복사할 수 없음
  • 실제로 제대로 복사하려면 import copycopy.deepcopy(복사하려는리스트)를 사용해야 함
    • 하지만 이 경우 import를 지원하지 않는 곳에서는 사용할 수 없음
  • 1차원 리스트는 깊은 복사가 가능하지만 2차원 리스트에서는 깊은 복사가 안 됨!
    • for ~ in 반복문으로 새로운 빈 배열에 하나씩 append하는 것으로 복사할 수 있음
      for i in a:
          b.append(i[:])
  • 슬라이싱은 index 값을 벗어나도 에러가 발생하지 않음
  • 슬라이싱은 도려낸 자리에 삽입도 가능함! ⇒ 여기서부턴 원본이 바뀜