[Python] 파이썬 기초 문법 정리

송히·2024년 4월 30일
0

개발 공부 🐨

목록 보기
9/15
post-thumbnail

파이썬 기초 문법을 익히면서 "오~ 이거 좀 신선하다 !!"라고 느꼈던 내용들을 정리해봤습니다 ㅎㅎ
JS와 다른 문법들 위주로 정리해봤으니까 가볍게 봐주세요 🙇🏻‍♀️

(이코테 2021 강의 몰아보기) 1. 코딩 테스트 출제 경향 분석 및 파이썬 문법 부수기


알고리즘 설계 Tip

  • 일반적으로 파이썬의 연산 횟수가 500,000,000 이상이면 5초~15초 소요
    -> 하지만 코테의 시간제한은 보통 1~5초임 (문제에 명시되어있지 않다면 5초라고 생각)
    => 파이썬이 1초에 20,000,000번의 연산만 처리할 수 있다고 가정하기

  • 때때로 PyPy가 더 빠름 (늘 그런 건 아님. 오히려 파이썬보다 메모리 소요가 더 클 때도 있음)
    -> 파이썬으로 코드 잘 짰는데도 시간 초과 발생하면 PyPy로도 한번 제출해보기 (해당 코테가 PyPy를 지원한다면...)


  • 시간 제한에 따른 시간복잡도 기준

    시간 제한n의 범위시간복잡도예상 소요 시간
    1초500O(N^3)125,000,000
    (=> 20,000,000 이하만 가능)2,000O(N^2)4,000,000
    100,000O(NlogN)1,151,293
    10,000,000O(N)10,000,000
  • 수행 시간 측정 소스 코드

    import time
    
    start_time = time.time()  # 측정 시작
    ~작성한 코드 넣기~
    end_time = time.time()  # 측정 종료
    print("수행 시간: ", end_time - start_time)  # 수행 시간 출력

자료형

정수형, 실수형

  • a/b: a 나누기 b의 값. 소수점까지 다 계산됨 -> 실수
  • a//b: a 나누기 b의 몫. 나눗셈의 몫만 계산됨
  • e 또는 E: 10의 지수 의미
    => 계산된 결과는 실수 데이터, 주로 임의의 큰 수를 표현할 때 사용

    num1 = 1e8  # 1 * 10^9 = 1,000,000,000.0
     num2 = 4e5  # 4 * 10^5 = 400,000.0
  • 컴퓨터가 계산한 실수끼리의 계산 값과 특정 실수값은 다를 수 있음
    ex) 0.3 + 0.6 != 0.9 (2진수 체계라서 완벽한 계산 불가)
    -> round(실수, 남겨둘 소수점 개수) 함수를 사용해 반올림하여 계산

     0.3 + 0.6 == 0.9  # False
      round(0.3 + 0.6, 2) == 0.9  # True

리스트

let으로 선언한 배열 같은 느낌.,, 요소 값 변경 가능 !!

  • 특정한 값으로 리스트 초기화하기 -> [값] * 요소 개수

    n = 5
     a = [0] * n  # a = [0, 0, 0, 0, 0] (크기는 n, 원소들은 0인 리스트)
  • 인덱싱: 인덱스로 접근해서 원소 찾기
    -> 음의 인덱스도 가능 !! (뒤에서부터 -1, -2 ,-3, ...)

  • 슬라이싱: 연속적인 원소들을 통으로 가져오는 것, 원본 변화 x
    -> list.[start:end+1]: start부터 end까지 잘라줌
    => [start:]: end 생략 -> start부터 끝까지
    => [:end+1]: start 생략 -> 처음부터 end까지
    => [:]: 처음부터 끝까지

  • 리스트 컴프리헨션: 대괄호 안에 조건문 & 반복분을 사용해서 리스트 초기화시킴 (만족하는 대상만 리스트로 생성)
    -> 한 줄로 표현 가능하면서 직관적이며 속도까지 빠름
    => [반복 요소 (for 변수 in 리스트) (if문)]

    numArr = [i for i in range(5)]  # [0, 1, 2, 3, 4]
     evevFourNumArr = [i for i in range(10) if i % 2 == 0 if i % 4 == 0]  # [4, 8]
     sqrtNumArr = [i*i for i in range(1, 5)]  # [1, 4, 9, 16]
  • 리스트 컴프리헨션을 이용한 2차원 리스트 초기화 가능
    -> 주의할 점: 리스트를 그저 단순 반복하는 잘못된 컴프리헨션을 사용하지 않아야함
    -> 전체 리스트 안에 포함된 각 리스트모두 같은 객체로 인식되어 이상한 결과 반환

    # n * m 크기의 2차원 리스트를 0으로 한방에 초기화
     n= 4
     m= 3
     nmArr = [[0] * m for _ in range(n)]  # [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
     nmArr[1][1] = 1  # [[0, 0, 0], [0, 1, 0], [0, 0, 0], [0, 0, 0]]
    
     # 잘못된 방법 -> 처음은 초기화된 것처럼 보이지만
     # 반복되는 부분들은 모두 같은 값을 가지게 되어 하나의 값을 바꾸면 반복되는 부분의 값이 전부 변경됨
     wrongArr = [[0] * m] * n  # [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
     wrongArr[1][1] = 1  # [[0, 1, 0], [0, 1, 0], [0, 1, 0], [0, 1, 0]]
  • _: 언더바, 반복을 수행하지만 반복을 위한 변수는 사용되지 않아 그 값을 무시하고 싶을 때 사용 (단순 반복)
for _ in range (5):
  print("Hello World")  # Hello World 5번 출력됨
  • 리스트 관련 주요 메서드

    함수의미시간복잡도함수의미시간복잡도
    append()리스트 끝에 원소 하나 삽입O(1)reverse()리스트의 순서를 반대로 뒤집음O(N)
    sort()오름차순 정렬O(NlogN)sort(reverse = True)내림차순 정렬O(NlogN)
    insert(삽입 위치, 삽입할 값)삽입할 위치 인덱스에 해당 값 끼워넣음O(N)count(특정한 값)리스트에서 특정한 값의 개수O(N)
    remove(특정한 값)리스트에서 맨 처음 만나는 특정한 값 하나 제거O(N)
    • 리스트에 존재하는 특정한 값을 모두 제거하고 싶은 경우

      arr = [1, 2, 3, 4, 5, 5, 5]
      removeNumsSet = {3, 5}
      
      result = [i for i in arr if not in removeNumsSet]  # [1, 2, 4], removeNumsSet에 속하지 않은 숫자들만 리스트로 반환
      			```

문자열 (변경 불가능)

  • 문자열 * 숫자(양의 정수): 숫자만큼 해당 문자열 더해짐(반복)

  • 문자열도 인덱싱, 슬라이싱 가능 (인덱스값 변경은 안 됨)

  • 여러 줄 문자 표현하기: 좌우에 백틱 3개씩 쓰고, 그 사이에 적으면 됨

     sentences = ```백틱 3개로
      여러 줄의 문자를
      표현할 수 있어요
      공백 띄어쓰기 다 가능 !!```
  • 문자열 메서드

    메서드의미메서드의미
    lower()문자열 소문자로 변환upper()문자열 대문자로 변환
    capitalize()문장 첫 글자만 대문자로 변환title()각 단어의 첫글자 대문자로 변환
    swapcase()대소문자 서로 반대로 변환split()문자열 분리
    startswith()해당 글자로 시작하는지 판별endswith()해당 글자로 끝나는지 판별
    strip()앞 뒤의 불필요한 ()안의 해당 부분 제거 //trim()과 비슷함replace(찾을 문자, 바꿀 문자, 바꿀 개수 (앞에서부터 셈)해당 단어 바꾸기
    find()단어 위치 찾기center()양 옆에 ()안 문자 붙여줌

튜플

const로 선언한 배열 같은 느낌.,, 요소값 변경 불가능

  • 튜플도 인덱싱, 슬라이싱 가능 (인덱스값 변경은 안 됨)

  • 리스트보다 제한된 기능만 사용 가능하기 때문에 리스트에 비해 공간 효율적(메모리 사용량 적음)

  • 튜플 사용이 유리한 경우

    1. 서로 다른 성질의 데이터 묶어서 관리하는 경우
      ex) (실수, 정수), (정수, 문자열), ...
    2. 데이터들을 해싱(사전 자료형, 집합 자료형)의 키 값으로 사용할 때 (해싱의 키 값은 변경 불가능한 값만 사용가능하기 때문)
    3. 리스트보다 메모리를 더 효율적으로 사용해야할 때

사전 자료형 (해싱)

키(Key)와 값(Value)의 쌍을 데이터로 가지는 자료형 (순서 없음)
-> 해시 테이블을 이용하므로 데이터 조회 및 수정상수시간 소요
=> Map같은 느낌 !!

  • .keys(): 키 데이터만 뽑아내는 함수 -> dict_keys([])
  • .values(): 값 데이터만 뽑아내는 함수 -> dict_values([])
# dict()으로 정의하시
data = dict()
data["사과"] = "Apple"
data["바나나"] = "Banana"
data["코코넛"] = "Coconut"

# 객체 형식으로 바로 정의하기
objectDict = {
  "체리": "cherry",
  "레몬": "lemon"
}

print(data)  # {"사과": "Apple", "바나나": "Banana", "코코넛": "Coconut"}
print(objectDict)  # {"체리": "cherry", "레몬": "lemon"}


if "사과" in data:  # True
if "망고" in data:  # False

data_keys = data.keys()  # dict_keys(['사과', '바나나', '코코넛'])
data_keys_list = list(data.keys())  # ['사과', '바나나', '코코넛']

data_values = data.values()  # dict_values(['Apple', 'Banana', 'Coconut'])

집합 자료형 (해싱)

중복을 허용하지 않고, 순서가 없는 자료형 -> 데이터의 존재 여부만을 체크함
-> 데이터 조회 및 수정상수시간 소요
=> Set 같은 느낌 !!

  • 집합 자료형의 연산

    1. a | b: A와 B의 합집합 (A U B)
    2. a & b: A와 B의 교집합 (A n B)
    3. a - b: A와 B의 차집합 (B - A도 가능)
  • 집합 자료형 관련 주요 함수

    1. add(): 새로운 원소 추가
    2. update([원소들]): 새로운 원소 여러 개 추가
    3. remove(): 특정한 값을 갖는 원소 삭제 -> 집합이라 어차피 1개뿐
# set() 함수를 이용해 집합 자료형 초기화 (문자열, 리스트 이용)
a = set([1, 1, 2, 3, 4, 4, 5])  # {1, 2, 3, 4, 5}
# 원소 직접 삽입해 집합 자료형 초기화
b = {3, 3, 4, 5, 6, 6, 7}  # {3, 4, 5, 6, 7}

print(a | b)  # {1, 2, 3, 4, 5, 6, 7}
print(a & b)  # {3, 4, 5}
print(a - b)  # {1, 2}
print(b - a)  # {6, 7}

a.add(8)  # {1, 2, 3, 4, 5, 8}
a.update([9, 10])  # {1, 2, 3, 4, 5, 8, 9, 10}
a.remove(9)  # {1, 2, 3, 4, 5, 8, 10}

형 변환

형 변환 문법의미형 변환 문법의미
int()정수float()실수
str()문자열bool()불리언값
  • float에서 int로 형 변환시 소수점은 전부 내림
  • bool()에서 값이 없을 때는 False
    => 0, "", None, [], ...

표준 입출력

표준 입력

  • input(): 한 줄의 문자열을 입력 받는 함수
  • map(): 리스트의 모든 원소에 각각 특정한 함수를 적용할 때 사용하는 함수
  • split(): 공백을 기준으로 데이터 구분
n = int(input())  # 1줄만 입력 받기 가능 ex) 5

# 공백을 기준으로 구분된 데이터 입력 받기
# -> 입력받은 공백 기준 구분된 한 줄 데이터(input().split())를 전부 숫자로 바꾼 뒤(map(int, inputData)) 리스트로 반환 
dataList = list(map(int, input().split()))  # ex) [10, 11, 12, 13, 14]

# 공백을 기준으로 구분된 데이터 입력 받기 (데이터 개수 안 많을 때)
a, b, c = map(int, input().split())  # ex) 10, 11, 12

  • sys.stdin.readline(): 최대한 빠르게 입력 받는 메서드, sys 라이브러리에 정의되어있음
    -> 입력하는 Enter가 줄 바꿈 기호로 같이 입력되므로, rstrip() 메서드를 함께 사용해야함
    => 입력의 개수가 많은 문제는 입력받는 시간때문에 시간초과 발생 가능 (이진탐색, 정렬, 그래프 문제에서 주로 사용)

    import sys
    
     data = sys.stdin.readline().rstrip()  # 한 줄로 입력된 문자열 입력받음

표준 출력

  • print(): 기본 출력 함수, 자동 줄바꿈됨
    -> 줄바꿈이 싫다면 end속성 이용해 마지막 부분 바꾸기

  • print()의 옵션

    옵션의미
    sep = "구분자"해당 구분자를 끼워 요소들 출력
    end = "구분자"서로 다른 print문을 연결할 때 구분자로 구분(기본 옵션 줄바꿈)
  • 파이썬은 문자열 + 정수로 출력 불가
    -> str(정수)로 바꿔서 연결해야함

    a = 1
     b = 2
    
     print(a, b)
     print(a, end=" ")
     print(b, end=" ")
     print("문자열과 숫자 " + str(a) + "를 연결해서 출력")
     # 1 2
     # 1 2 문자열과 숫자 1를 연결해서 출력
  • 출력을 위한 문자열 포맷

    1. f-string: 문자열 앞에 f를 붙여 사용, 숫자도 형변환 필요 없음 (파이썬 3.6 이상만 가능)
      print(f"문자열과 숫자 {a}를 연결해서 출력)
       # 문자열과 숫자 1를 연결해서 출력
       print(f"제가 좋아하는 과일은 {사과}, {망고}입니다.")
       # 제가 좋아하는 과일은 사과, 망고입니다.
    2. {} 포맷
      # {} + 포맷 -> 순서대로 매칭
       print("제가 좋아하는 과일은 {}, {}입니다.".format(사과, 망고))  # 제가 좋아하는 과일은 사과, 망고입니다.
       
       # {N} + 포맷 (N = 0, 1, 2, ...) -> 번호에 맞게 매칭됨
       print("제가 좋아하는 과일은 {1}, {0}입니다.".format(사과, 망고))  # 제가 좋아하는 과일은 망고, 사과입니다.

조건문과 반복문

  • 블럭(Block): 한 기능을 수행하기 위한 코드의 묶음
    -> 블럭 구분은 들여쓰기(Indent)으로 지정함 (같은 들여쓰기 부분이 한 블럭)
  • range(시작값, 끝값+1) => 인자가 1개이면 시작값이 0으로 간주됨
  • if ~ elif ~ else문: else if가 elif임
    -> 조건문에서 실행되는 코드가 한 줄이면, 줄바꿈 하지 않고 한 줄에 써도 됨 !

  • 삼항연산자: True일 때의 실행 코드 if 조건 else False일 때 실행 코드

  • 파이썬의 부등식은 연속비교를 허용함 ex) 0 < x < 20
    -> 다른 언어의 x > 0 and x < 20과 같은 의미
    => 하지만 다른 언어와 동일한 문법을 쓰는 것을 추천

  • for 변수 in 데이터들(리스트, 튜플, ...): 데이터들에 포함된 원소를 첫 번째 인덱스부터 차례대로 방문

  • pass: 그냥 통과시킬 코드 블럭, 기능을 하지 않고 일단 비워두는 부분


print("만점입니다." if score === 100 else "채점이 필요합니다.")

if score > 90:
  pass  # 해당 조건에 해당되어도 어떠한 기능 없이 다음으로 넘어감
elif score > 80: 
  print("80점이 넘는 점수입니다.")
  print("B등급 입니다.")
else: print("C등급 입니다.")  # 줄바꿈 없이 한 줄에 작성

print("채점 끝!")

  • 논리 연산자: 기호 대신 영어 단어를 씀 !!

    논리 연산자의미
    X and Y둘 다 참일 경우 (= &&)
    X or Y둘 중 하나만 참이어도 되는 경우
    not XX가 거짓이어야 참인 경우
  • 멤버 연산자: 여러 개의 데이터를 담는 자료형에 사용(리스트, 튜플, 문자열, 딕셔너리, ...)

    멤버 연산자의미
    x in 데이터데이터 안에 x가 있어야 참
    x not in 데이터데이터 안에 x가 없어야 참
    # 멤버 연산자 사용법
    print("a" in "apple") # True
     print("a" in [1, 2, 3, 4, 5]) # False
     print("a" not in "apple") # False
     print("a" not in "banana") # True

함수

  • 인자(args): 함수를 호출할 때 전달하는 값
    ex) print(func(1, 2))
  • 매개변수(parameter): 함수를 생성할 때 받는 값
    ex) def func(a, b): ~
  • 파이썬은 파라미터의 변수를 직접 지정할 수 있음
    -> 파라미터와 인자의 순서가 달라도 상관 없음 !!

  • global: 함수 안에서 사용되는 전역 변수에 global 키워드를 붙이면 함수 바깥에 선언된 전역 변수값을 바로 참조하기 때문에, 함수 안에서 사용하려는 변수를 또 선언하지 않아바깥 전역 변수 사용 가능 (안에서 값 바꾸면 전역변수의 값도 바뀜)
    => 함수 안에서 함수 바깥에 선언된 전역변수를 바로 사용하겠다고 명시하는 키워드
    -> 값 변경 / 새로운 값 대입이 아닌 단순한 값 참조의 경우에는 굳이 안 붙여도 됨
    -> 전역 변수 리스트에 append()로 단순히 값 추가할 때도 없어도 됨

  • 패킹: 함수가 여러 개의 값을 한번에 반환하는 것 (반환된 순서에 맞게 값 저장됨)

    def minus(a, b):
       print(a - b)
    
     minus(5, 2)  # 3
     minus(b = 2, a = 5)  # 3
    
    
     k = 0
     l = [1, 2, 3, 4, 5]
       
     def func(): 
       print(k + 20)  # 20, 단순히 값 참조하는 것이기 때문에 global 키워드 / 재정의 없어도 오류 안 뜸
       l.append(6)  # [1, 2, 3, 4, 5, 6], 단순한 값 추가라 오류 안 뜸
     
     def func_1():
       k = 0  # 이 구문 없으면 k가 정의되지 않았다는 오류 뜸
       k += 1
       print(k)  # 1, func_2()와 같은 의미의 함수
         
     def func_2():
       global k
       k += 1
       print(k)  # 1, func_1()와 같은 의미의 함수
       l = [3, 4, 5]
       l.append(6)  # [3, 4, 5, 6], global 없으니 같은 이름이어도 함수 안에서 새로 정의된 같은 이름의 변수가 우선시됨
       
       
     def packingFunc(a, b):
       return a+b, a-b, a*b
       
     plus, minus, multip = packingFunc(2, 1)  # 3, 1, 2
       

람다 표현식

특정한 기능을 수행하는 함수를 한 줄에 바로 작성할 수 있음
=> (lambda (매개변수): 반환 결과)(인자)
-> 이름없는 함수라고도 불림

  • 람다 표현식이 유용한 경우
    1. 함수 자체를 입력으로 받는 함수에서 사용할 때 (특히 내장함수)
    2. 여러 개의 리스트에 하나의 함수를 적용할 때
    3. 함수의 기능이 매우 간단할 때 / 한번만 사용할 함수일 때
students = [("영희", 50), ("민호", 30), ("철수", 75)]

def scores(x):
  return x[1]
print(sorted(students, key = scores))  # [("민호", 30), ("영희", 50), ("철수", 75)]

print(sorted(students, key = lambda x: x[1]))  # [("민호", 30), ("영희", 50), ("철수", 75)]


list_1 = [1, 2, 3, 4, 5]
list_2 = [6, 7, 8, 9, 10]
result = map(lambda a, b: a + b, list_1, list_2)  # [7, 9, 11, 13, 15]

유용한 표준 라이브러리

  1. 내장 함수: 별도의 import 필요 없음
    => 기본 입출력, 정렬 등 필수 기본 함수 제공

    eval("(3+5) * 7")  # 56, 수식의 형태를 계산해서 숫자로 반환해줌
  2. itertools: 반복되는 형태의 데이터를 처리하기 위한 기능
    => 특히 순열, 조합 라이브러리가 모든 경우를 고려해야하는 문제에 사용됨(완전 탐색 문제)

    data = ['A', 'B', 'C']
    
     from itertools import permutations  # 순열 import
     permutation = list(permutations(data, 3))  # [('A','B','C'), ('A','C','B'), ('B','A','C'), ('B','C','A'), ('C','A','B'), ('C','B','A')]
     # -> 모든 순열(3개를 선택해 순서대로 나열) 구해서 list로 반환
     
     from itertools import product  # 중복 순열 import
     dupPermutation = list(product(data, repeat=2))
     # -> 2개 뽑는 모든 순열 구하기 (중복 허용)
     
     from itertools import combinations  # 조합 import
     combination = list(combinations(data, 2))  # [('A','B'), ('A','C'), ('B','C')]
     # -> 2개를 뽑는 모든 조합 구해서 list로 반환
     
     from itertools import combinations with_replacement  # 중복 조합 import
     dupCombination = list(combinations_ith_replacement(data, 2))
     # -> 2개를 뽑는 모든 조합 구해서 list로 반환 (중복 허용)
  3. heapq: 힙(Heap) 자료구조 제공
    => 일반적으로 우선순위 큐를 구현하기 위해 사용됨 (다익스트라 같은 최단 경로 알고리즘)

  4. bisect: 기본적인 이진 탐색(Binary Search) 기능

  5. collections: 덱(deque), 카운터(Counter) 등의 자료구조 포함
    => Counter: 반복 가능한 객체의 내부에 해당 원소가 등장한 횟수 세어줌

from collections import Counter  # Counter import

counter = Counter(['red', 'blue', 'red', 'green', 'blue', 'blue'])
print(counter['blue'])  # 3, 'blue'가 등장한 횟수
print(counter['green'])  # 1, 'green'이 등장한 횟수
print(dict(counter))  # {'red': 2, 'blue': 3, 'green': 1}, 사전 자료형으로 각 요소별 개수 반환
  1. math: 필수적인 수학 기능
    => 팩토리얼, 제곱근, 최대공약수(GCD), 최소공배수(LCM), 삼각함수 관련 함수, 파이(pi), ...
profile
데브코스 프론트엔드 5기

0개의 댓글

관련 채용 정보