SECTION 011. Python의 기초
1. Python의 기본 문법
- 
    
변수의 자료형에 대한 선언이 없다.
– Python은 변수에 저장되는 값에 따라 자동으로 자료형이 지정된다. - 
    
문장의 끝을 의미하는 세미콜론(;)을 사용할 필요가 없다.
 - 
    
변수에 연속하여 값을 저장하는 것이 가능하다.
– 예) x, y, z = 10, 20, 30 - 
    
if나 for와 같이 코드 블록을 포함하는 명령문을 작성할 때, 코드 블록은 콜론(:)과 여백으로 구분한다.
– 같은 수준의 코드는 반드시 동일한 여백을 가져야 한다. 
  if a>b :
    print('a')
  else :
    print('b')
2. Python의 데이터 입출력 함수
1) input() 함수
- input() 함수는 Python의 표준 입력 함수로, 키보드로 입력받아 변수에 저장하는 함수이다.
 - 입력되는 값은 문자열 로 취급되어 저장된다.
 
(1) 1개의 데이터 입력
  변수 = input('출력문자')
– ‘출력문자’는 생략이 가능하며, 변수는 사용자가 임의로 지정할 수 있다.
– 화면에 ‘출력문자’가 출력되고, 그 뒤에 커서가 깜빡이며 입력을 기다린다. 키보드로 값을 입력하고 ‘Enter’를 누르면 입력한 값이 변수에 문자열로 저장된다.
(2) 2개 이상의 데이터 입력
  변수1, 변수2, ... = input('출력문자').split('분리문자')
– 2개 이상의 값을 분리하여 입력받기 위해 사용한다.
– 화면에 ‘출력문자’가 표시되고, 입력받은 값을 ‘분리문자’를 기준으로 구분하여 각각 변수1, 변수2, …에 저장한다.
– ‘분리문자’를 생략하면 공백으로 값을 구분한다.
(3) 입력 값의 형변환
– input() 함수는 입력되는 값을 문자열로 저장하므로, 숫자로 사용하기 위해서는 형변환이 필요하다.
- 입력받은 데이터가 1개일 때
 
  변수 = int(input())   // 정수로 변환
  변수 = float(input())  // 실수로 변환
- 입력받은 데이터가 2개 이상일 때
– map() 함수를 사용해야 한다. 
  변수1, 변수2, ... = map(int, input().split())
  변수1, 변수2, ... = map(float, input().split())
2) print() 함수
(1) 형식 1
  print(출력값1, 출력값2, ..., sep = '분리문자', end = '종료문자')
- 출력값 : 숫자, 문자, 문자열, 변수 등 다양한 값이나 식을 사용할 수 있다.
 - sep : 여러 값을 출력할 때, 값과 값 사이를 구분하기 위해 출력하는 문자
– ‘분리문자’를 생략하는 경우 기본값은 공백 한 칸(‘ ‘) 이다. - end : 맨 마지막에 출력할 문자로, 생략할 경우 기본값은 줄 나눔(‘\n’) 이다.
 
(2) 형식 2
  print('서식 문자열'%출력값)
  print('서식 문자열'%(출력값1, 출력값2, ...))
- ‘SECTION 003 데이터 입출력’ 에서 사용한 서식 문자열이 동일하게 적용된다.
– 예) ‘%d’ : 정수형 10진수, ‘%s’ : 문자열 - 출력값이 한 개인 경우 출력값의 괄호를 생략할 수 있다.
 
3. Python의 문자열
1) 사용법
- 
    
Python에서 문자열은 작은따옴표(‘ ‘), 큰따옴표(“ “), 3개의 작은따옴표(‘’’ ‘’’), 3개의 큰따옴표(“”” “””) 로 묶어서 표현할 수 있다.
– Python은 하나의 문자를 지정하는 char 자료형이 없기 때문에, 작은따옴표와 큰따옴표를 자유롭게 사용할 수 있다. - 
    
문자열 내에 따옴표가 사용될 경우, 다른 따옴표로 전체 문자열을 묶는다.
– 예) x = ‘ I’m tired ‘ → 문자열이 정상적으로 묶이지 않아 오류가 발생한다.
– 예) x = “ I’m tired “ → 작은따옴표가 사용된 문자열이 큰따옴표로 묶여 정상적으로 저장된다. - 
    
3개의 따옴표를 사용하면, 문자열 내에서 작은따옴표와 큰따옴표를 자유롭게 사용할 수 있다.
– 예) x = ‘’’ I’m “tired” ‘’’ → 작은따옴표와 큰따옴표가 모두 포함된 문자열이 3개의 따옴표로 묶여 저장된다. - 
    
제어문자를 사용할 수 있다.
– ‘SECTION 003 데이터 입출력’ 에서 사용한 제어문자가 동일하게 적용된다.
– 예) ‘\n’ : 줄바꿈, ‘\t’ : 일정 간격 띄움 
2) 문자열의 주요 메소드
| 형식 | 내용 | 
|---|---|
| upper() | 대문자로 변경한다. - 예) ‘abc’.upper() → ABC  | 
    
| lower() | 소문자로 변경한다. - 예) ‘ABC’.lower() → abc  | 
    
| capitalize() | 문자열 첫 글자는 대문자, 나머지는 모두 소문자로 변경한다. - 예) ‘abcD EF’.capitalize() → Abcd ef  | 
    
| title() | 각 단어의 첫 글자만 대문자로 변경한다. - 예) ‘abcD EF’.title() → Abcd Ef  | 
    
| replace(값1, 값2) | 문자열에서 ‘값1’을 찾아 ‘값2’로 교체한다. - 예) ‘abcde’.replace(‘c’, ‘o’) → abode  | 
    
| split(값) | ‘값’을 기준으로 문자열을 분리하여 리스트로 반환한다. ‘값’을 생략하면 공백(‘ ‘)으로 문자열을 분리한다 - 예) ‘ab-cd’.split(‘-‘) → [‘ab’, ‘cd’]  | 
    
| count(값) | 문자열에서 ‘값’을 검색하여 ‘값’의 개수를 반환한다. - 예) ‘aababc’.count(‘b’) → 2  | 
    
| find(값) | 문자열에서 처음 검색되는 ‘값’의 위치를 반환한다. ‘값’을 찾지 못한 경우는 -1 을 반환한다. - 예) ‘aababc’.find(‘b’) → 2  | 
    
| index(값) | 문자열에서 처음 검색되는 ‘값’의 위치를 반환한다. ‘값’을 찾지 못한 경우는 오류가 발생한다. - 예) ‘aababc’.index(‘b’) → 2  | 
    
- Python 에서 문자열 위치는 ‘0’ 부터 시작한다.
 
3) 문자열 Formatting - f-Strings
- 문자열 Formatting 은 기존 변수에 저장된 값을 사용하여 문자열을 조정하는 것이다.
 - f-Strings 을 사용할 문자열 앞에는 f 또는 F 를 붙인다.
 
– 예제)
  name = 'abc'
  num = '10'
  x = f"Hello {name}, you're {num}th user"
  print(x)
– 실행결과)
Hello abc, you’re 10th user
4. 리스트(List)
1) 개념
- C 와 Java 에서는 여러 요소들을 한 개의 이름으로 처리할 때 배열을 사용하고, Python 에서는 리스트를 사용한다.
– Python 은 기본 자료형으로 배열 (Array) 을 제공하지 않는다. - 리스트는 필요에 따라 개수가 달라지기 때문에 리스트를 선언할 때 크기를 지정하지 않는다.
 - 배열과 달리 리스트는 정수, 실수, 문자열 등 다양한 자료형을 저장할 수 있다.
 - Python 에서 리스트의 위치는 ‘0’ 부터 시작한다.
 
2) 1차원 리스트
(1) 형식
  리스트명 = [ 값1, 값2, ... ]
  리스트명 = list([ 값1, 값2, ... ])
- 리스트명은 사용자가 임의로 지정할 수 있으며, 리스트를 의미하는 대괄호 [] 사이에 저장할 값들을 쉼표(,)로 구분하여 입력한다.
 
– 예제)
  a = [ 10, 'mike', 23.45]
  a = list([ 10, 'mike', 23.45 ])
  # - 두 방법에 대한 결과는 동일하다.
  ''' a[0]    a[1]    a[2]
      10      mike    23.45
  '''
(2) 추가
- append() : 리스트의 마지막에 값을 추가할 때 사용한다.
 
– 예제)
  a.append('B')
  # 리스트 a의 마지막에 'B'를 추가한다.
  ''' a[0]    a[1]    a[2]    a[3]
      10      mike    23.45   B
  '''
(3) 삽입
- insert() : 리스트의 중간에 값을 삽입할 때 사용한다.
 
– 예제)
  a.insert(1, 777)
  # 리스트 a의 두 번째 자리(a[1])에 777을 추가한다.
  # 이후 요소들은 한 칸씩 뒤로 이동한다.
  ''' a[0]    a[1]    a[2]    a[3]    a[4]
      10      777     mike    23.45   B
  '''
(4) 삭제
- del : 리스트의 위치를 기준으로 요소를 삭제한다.
 - remove() : 리스트의 값을 기준으로 요소를 삭제한다.
 
– 예제 1)
  del a[3]
  # 리스트 a의 네 번째 요소(23.45)를 삭제한다.
  # 이후 요소들은 한 칸씩 앞으로 이동한다.
  ''' a[0]    a[1]    a[2]    a[3]
      10      777     mike    B
  '''
– 예제 2)
  a.remove(777)
  # 리스트 a에서 값 777을 찾아 해당 요소를 삭제한다.
  # 이후 요소들은 한 칸씩 앞으로 이동한다.
  ''' a[0]    a[1]    a[2]
      10      mike    B
  '''
– 예제 3)
  del a
  # 리스트 a 자체를 삭제한다.
3) 2차원 리스트
- 2차원 리스트는 리스트에 리스트를 저장하는 방식으로 구현한다.
 
(1) 형식 1
  리스트명 = [ [ 값1, 값2, 값3 ],
              [ 값4, 값5, 값6 ] ]
(2) 형식 2
  리스트A = [ 값1, 값2, 값3 ]
  리스트B = [ 값4, 값5, 값6 ]
  리스트명 = [ 리스트A, 리스트B ]
– 예제)
  b = [ [ 1,2,3 ], [ 'a', 'b', 'c' ] ]
  ''' b[0][0]  b[0][1]  b[0][2]
        1        2        3
      b[1][0]  b[1][1]  b[1][2]
        a        b        c
  '''
4) 리스트의 주요 메서드
| 형식 | 내용 | 
|---|---|
| pop(위치) | 리스트의 ‘위치’에 있는 값을 출력하고, 해당 요소를 삭제한다. - 예) [10, 11, 12].pop(11) → 11 출력 → [10, 12]  | 
    
| index(값) | 리스트에서 ‘값’이 저장된 요소의 위치를 반환한다. - 예) [10, 11, 12].index(12) → 2  | 
    
| count(값) | 리스트에서 ‘값’이 저장된 요소의 개수를 반환한다. - 예) [1, 0, 1, 0, 0].count(0) → 3  | 
    
| extend(리스트) | 리스트의 끝에 새로운 ‘리스트’를 추가하여 확장한다. - 예) [‘a’, ‘b’].extend(‘c’, ‘d’) → [‘a’, ‘b’, ‘c’, ‘d’]  | 
    
| reverse() | 리스트의 순서를 역순으로 뒤집는다. - 예) [1, 2, 3].reverse() → [3, 2, 1]  | 
    
| sort() | 리스트를 정렬한다. 기본값은 오름차순이다. reverse 속성을 이용하여 정렬 방식을 지정할 수 있다. - True : 내림차순, False : 오름차순 - 예) [2, 1, 3].sort() → [1, 2, 3] [2, 1, 3].sort(reverse = True) → [3, 2, 1]  | 
    
| copy() | 리스트를 복사한다. - 예) a = [1, 2, 3] b = a.copy() → b = [1, 2, 3]  | 
    
- copy() 메서드를 사용하지 않고, b = a 와 같이 리스트를 복사하면, 두 개의 리스트가 같은 메모리를 공유하기 때문에, 한 쪽의 리스트가 수정되면 다른 한 쪽에도 반영된다. 따라서 리스트를 복사하여 별도의 자료 공간으로 사용하기 위해서는 copy() 메서드를 사용해야 한다.
 
5. Range
- Range 는 연속된 숫자를 생성하는 것으로, 리스트, 반복문 등에서 많이 사용된다.
 
1) 형식
(1) range(최종값)
- 0에서 ‘최종값-1’ 까지 연속된 숫자를 생성한다.
 
– 예제)
  a = list(range(5))
  # 0에서 4까지 연속된 숫자를 리스트 a에 저장한다.
  # 0, 1, 2, 3, 4
(2) range(초기값, 최종값)
- ‘초기값’에서 ‘최종값-1’ 까지 연속된 숫자를 생성한다.
 
– 예제)
  a = list(range(4,9))
  # 4에서 8까지 연속된 숫자를 리스트 a에 저장한다.
  # 4, 5, 6, 7, 8
(3) range(초기값, 최종값, 증가값)
- ‘초기값’에서 ‘최종값-1’ 까지 ‘증가값’만큼 증가하면서 숫자를 생성한다.
 - ‘증가값’이 음수인 경우, ‘초기값’에서 ‘최종값+1’ 까지 ‘증가값’만큼 감소하면서 숫자를 생성한다.
 
– 예제)
  a = list(range(1, 15, 3))
  # 1에서 14까지 3씩 증가하는 숫자들을 리스트 a에 저장한다.
  # 1, 4, 7, 10, 13
  a = list(range(9, 4, -1))
  # 9에서 5까지 -1씩 감소하는 숫자들을 리스트 a에 저장한다.
  # 9, 8, 7, 6, 5
6. 슬라이스 (Slice)
- 슬라이스는 문자열이나 리스트와 같은 순차형 객체에서 일부를 잘라 반환하는 기능히다.
 
1) 형식
(1) 객체명[초기위치:최종위치]
- ‘초기위치’에서 ‘최종위치-1’ 까지의 요소들을 가져온다.
 
(2) 객체명[초기위치:최종위치:증가값]
- ‘초기위치’에서 ‘최종위치-1’ 까지 ‘증가값’만큼 증가하면서 해당 위치의 요소들을 가져온다.
 - ‘증가값’이 음수인 경우, ‘초기위치’에서 ‘최종위치+1’ 까지 ‘증가값’만큼 감소하면서 해당 위치의 요소들을 가져온다.
 
2) 인수 생략
- 슬라이스는 일부 인수를 생략하여 사용할 수 있다.
 
(1) 객체명[:] 또는 객체명[::]
- 객체의 모든 요소를 반환한다.
 
(2) 객체명[초기위치:]
- 객체의 ‘초기위치’에서 마지막 위치까지의 요소들을 반환한다.
 
(3) 객체명[:최종위치]
- 객체의 0번째 위치에서 ‘최종위치-1’ 까지의 요소들을 반환한다.
 
(4) 객체명[::증가값]
- 객체의 0번째 위치에서 마지막 위치까지 ‘증가값’만큼 증가하면서 해당 위치의 요소들을 반환한다.
 
3) 예제
(1) 예제 1
  a = ['a', 'b', 'c', 'd', 'e']
  a[1:3] → ['b', 'c']
  # 객체의 1번째 위치에서 2번째 위치까지의 요소들을 가져온다.
  a[0:5:2] → ['a', 'c', 'e']
  # 객체의 0번째 위치에서 4번째 위치까지 2만큼 증가하면서 해당 위치의 요소들을 가져온다.
  a[3:] → ['d', 'e']
  # 객체의 3번째 위치에서 마지막 위치까지의 요소들을 반환한다.
  a[:3] → ['a', 'b', 'c']
  # 객체의 0번째 위치에서 2번째 위치까지의 요소들을 반환한다.
  a[::3] → ['a', 'd']
  # 객체의 0번째 위치에서 마지막 위치까지 3만큼 증가하면서 해당 위치의 요소들을 가져온다.
(2) 예제 2
  a = 'sinagong'
  print(a[3:7])
  # agon
  a = list(range(10))
  print(a[:7:2])
  # a = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
  # [0, 2, 4, 6]
  a = 'hello, world'
  print(a[7:])
  # world
  a = list(range(5, 22, 2))
  print(a[::3])
  # a = 5, 7, 9, 11, 13, 15, 17, 19, 21
  # [5, 11, 17]
  a = list(range(8))
  print(a[2::2])
  # a = 0, 1, 2, 3, 4, 5, 6, 7
  # [2, 4, 6]
  a = list(range(8, 3, -1))
  print(a[:3])
  # a = 8, 7, 6, 5, 4
  # [8, 7, 6]