Python_Day.1

조현기·5일 전

Python_Day.1

JavaScript 다음으로 만난 두 번째 언어, Python.
자료형 9가지, 문자열 다루기, 그리고 출력 서식(%, format, f-string)과 리스트까지.

JS를 먼저 배운 덕분에 코딩 자체에는 어느 정도 적응이 된 편이다. Python은 JS와 비슷한 것도 있고, 다른 것도 있고, 없는 것도 있었다. 오늘 배운 내용은 이렇다.

  1. Python의 자료형 9가지와 숫자 연산, 형 변환
  2. 문자열: 이스케이프 코드, 따옴표, 인덱싱과 슬라이싱
  3. 출력 서식: % 서식 문자, format(), f-string
  4. 리스트: 특징, 인덱싱·슬라이싱, 수정·삭제, 메소드

1. Python의 자료형 9가지

자료형이름예
int정수3
float실수10.4
complex복소수3+4j
bool불린True, False
str문자열'Python'
list리스트[1, 2, 3]
tuple튜플(4, 2, 4)
set집합{1, 23, 4}
dict사전(딕셔너리){'name': 'gildong', 'id': 3}
# 데이터 타입
str1 = 'Python'
float1 = 10.4
int1 = 3
bool1 = True
list1 = [str1]                    # list는 대괄호
tuple1 = 4, 2, 4
set1 = {1, 23, 4}                 # 중괄호로 집합 형태
dict1 = {'name': 'gildong', 'id': 3}   # JS의 객체와 비슷한 모양

# 데이터 타입 출력
print(type(str1))      # <class 'str'>
print(type(bool1))     # <class 'bool'>
print(type(float1))    # <class 'float'>
print(type(int1))      # <class 'int'>
print(type(list1))     # <class 'list'>
print(type(tuple1))    # <class 'tuple'>
print(type(dict1))     # <class 'dict'>
print(type(set1))      # <class 'set'>

파이썬은 모든 것이 객체다. str1 = 'Python'이라고 쓰면 문자 자체가 객체가 되고, 그 객체에 다양한 속성(변수)과 행동(함수)이 붙어 있다. JS의 typeof에 해당하는 것이 type()이다.

JS와 비교하면서 눈에 띈 부분을 표로 모아 둔다.

항목JavaScriptPython
주석//#
변수 선언let, const키워드 없이 x = 3
불린true, falseTrue, False (첫 글자 대문자)
타입 확인typeof(x)type(x)
키-값 구조객체 { }dict { }
배열배열 [ ]배열이 없고 list [ ]
거듭제곱Math.pow(3, 4)3 ** 4, pow(3, 4)
문장 끝;필요 없음

빈 중괄호 {}는 집합(set)이 아니라 빈 딕셔너리다. 빈 집합은 set()으로 만든다.

숫자형 연산

# 숫자형 연산자: +, -, *, /, %
i1 = 30
i2 = 944
big_int1 = 12345678123567891231234213546351356
big_int2 = 99999999999999999999999999999999999999

print(i1 + i2)            # 974
print(big_int1 + big_int2)   # 정수 크기에 제한이 없다 (메모리가 허용하는 범위까지)

print(3 ** 4)             # 81  (n ** m = n의 m승)

JS에서는 정수가 어느 크기를 넘으면 정확하게 표현할 수 없었지만, Python의 int는 크기 제한이 없다.

# 실수의 사칙연산
f1 = 1.234
f2 = 5.678
print(f1 + f2)            # 6.912
print(f1 - f2)            # -4.444
print(f1 * f2)            # 7.006652
print(f1 / f2)            # 0.2173300457907714

형 변환

a = 3.
b = 10
c = .5
d = 12.5

print(type(a), type(b), type(c), type(d))   # 한 줄에 여러 개를 출력할 수 있다
# <class 'float'> <class 'int'> <class 'float'> <class 'float'>

# 정수 → 실수
print(float(b))           # 10.0   (변환할 객체를, 바꾸고 싶은 클래스로 감싼다)

# 실수 → 정수
int(c)                    # c 자체가 바뀌지는 않는다
print(c)                  # 0.5
print(int(c))             # 0   (0.5 → 0, 소수점 이하가 버려진다)

# bool → 숫자
print(int(True))          # 1
print(float(True))        # 1.0
print(int(False))         # 0
print(float(False))       # 0.0

3.처럼 소수점 뒤를 비워도, .5처럼 앞을 비워도 실수로 인식된다. float()나 int()처럼 변환하고 싶은 클래스 이름으로 감싸는 방식이 JS의 Number(), parseInt()와 비슷하다. True는 1, False는 0이다.

# 수치 함수
print(abs(-42))           # 42  (절댓값)
print(pow(3, 4))          # 81  (밑수와 지수)

Python에서도 =는 대입 연산자다.


2. 문자열

이스케이프 코드

코드의미
\n개행 문자 (엔터)
\t탭
\\문자 \ 자체
\'작은따옴표 (작은따옴표로 감싼 문자열 안에 '를 넣을 때)
\"큰따옴표 (위와 동일)
\000\ 뒤에 8진수를 붙여 해당 아스키 문자를 표현 (거의 쓰지 않음)
print('Hello\nWorld')       # Hello (줄바꿈) World
print('Hello\tWorld')       # Hello    World
print('Hello\\World')       # Hello\World
print('Hello\'World')       # Hello'World
print('Hello\"World')       # Hello"World
print('Hellod\063World')    # Hellod3World  (8진수 063 = 아스키 '3')
print('\000')               # 화면에 보이지 않는 null 문자

문자열을 쓰는 방법

print('python welcome')
print("python welcome")

print('''python
        wel
        come''')                # 여러 줄에 걸쳐 출력할 때 유용
print("""python
        wel
        come""")                # 위와 동일

print()                         # 빈 줄(엔터)

print("Python's favorite food is perl")
# 큰따옴표 안에 작은따옴표를 넣어도 된다

# print('Python's favorite food is perl')
# 작은따옴표 안에 작은따옴표를 넣으면 오류 발생

say = '"Python is very easy" he says'
# 반대로 큰따옴표를 출력하고 싶으면 작은따옴표로 감싼다
print(say)

작은따옴표(')와 큰따옴표(")는 JS처럼 둘 다 문자열을 만들 수 있어서, 안에 들어갈 따옴표와 다른 쪽으로 감싸면 이스케이프가 필요 없다. 따옴표 세 개(''', """)로 감싸면 여러 줄 문자열이 된다. JS의 템플릿 리터럴(백틱) 중 줄바꿈 기능과 비슷하다.

인덱싱과 슬라이싱

len()은 문자열의 길이를 구하는 함수다. 띄어쓰기도 포함해서 센다. 파이썬도 숫자를 0부터 센다.

str1 = 'Python interesting'

print(str1[7])              # i
print(str1[0:3])            # Pyt     (0~2)
print(str1[:])              # Python interesting  (처음부터 끝까지)
print(str1[:4])             # Pyth    (0~3)
print(str1[4:])             # on interesting  (인덱스 4부터 끝까지)
print(len(str1))            # 18
print(str1[:len(str1)])     # 전체 (0부터 길이-1까지)
print(str1[1:-2])           # ython interesti  (인덱스 1부터 -2 미만까지)
print(str1[-4:-2])          # ti
print(str1[1:4:2])          # yh   (인덱스 1부터 3까지, 2칸씩 점프)

슬라이싱은 [시작:끝:증감] 형태다. 뒤에 오는 숫자(끝)는 "미만"이라는 점을 기억해야 한다. 음수 인덱스는 뒤에서부터 센다(-1이 마지막 글자). 세 번째 값은 건너뛰는 간격이다.

JS에서 substring, slice, charAt으로 따로 하던 것을 Python은 대괄호 하나로 한다.

실습: 주민등록번호 나누기

# 주민번호를 연월일 부분과 뒤 숫자 부분으로 나누어 출력
pin = '881120-1068234'

yyyymmdd = '19' + pin[:6]     # 앞에 '19'를 붙여서 1988이 되도록
num = pin[7:]
print(yyyymmdd)               # 19881120
print(num)                    # 1068234

# 뒷자리 첫 번째 숫자(성별을 나타내는 숫자)
print(pin[7])                 # 1

3. 출력 서식

① % 서식 문자 (C 스타일)

서식의미
%s문자열
%d정수
%f실수
%c문자 1개
print('문자열 %s와 문자열 %s가 있다.' % ('one', 'two'))
# 문자열을 끝내고, 배치할 값을 % 뒤 괄호에 한 번에 정리

print('%d %f %s' % (3, 7.6, 'abc'))    # 3 7.600000 abc
  • %f는 기본적으로 소수 6자리까지 출력한다.
  • 서로 섞어 쓸 수 있다.
  • 값이 하나뿐이면 괄호를 생략해도 된다.

칸 수와 정렬

print('%10s' % 'hello')         # 10칸에서 오른쪽 정렬 (앞에 공백 5칸)
print('%-10sBut' % 'go home')   # 10칸에서 왼쪽 정렬, 뒤에 But

print('%d,%d' % (4, 6))         # 4,6
print('%20s' % 'python')        # 20칸에서 오른쪽 정렬

print('%.4f' % 3.1424885)       # 3.1425  (3.1424가 아니라 반올림되어 3.1425)
print('%10.4f' % 3.1424885)     # '    3.1425' (10칸, 소수점 4자리, 오른쪽 정렬)
print('%.5s' % 'python javascript')   # pytho  (5글자까지만 출력, 절삭)
print('%06.2f' % 3.1475861254)  # 003.15  (총 6칸, 소수 2자리, 빈칸은 0으로)

% 앞의 -는 왼쪽 정렬, .숫자는 소수점 자릿수(문자열이면 글자 수), 앞에 0을 붙이면 빈 공백을 0으로 채운다.

x = 30
y = 50
z = 17650
name = 'Kim'
ex1 = '%s %f %d' % (name, z, (x + y))
print(ex1)                      # Kim 17650.000000 80
print(type(z))                  # <class 'int'>  (z 자체는 정수 그대로)

%f로 출력했어도 z가 실수로 바뀌는 것은 아니다. 출력 모양만 바뀐다.

필기 코드에서는 위의 name 자리에 str='Kim'처럼 str을 변수 이름으로 썼다. str은 Python이 이미 쓰고 있는 이름(문자열 클래스)이라, 이렇게 덮어쓰면 뒤에서 str(60)처럼 형 변환에 쓸 때 'str' object is not callable 오류가 난다. 위 코드에서는 name으로 바꿨고, 아래 f-string 예제도 같다.

② format() 함수

print('I eat {0} apples.'.format(3))
# format은 문자, 실수, 정수를 구분하지 않는다. 소속된 순서(0~n)대로 들어간다

print('{} {}'.format('one', 'two'))     # one two  (번호를 굳이 안 써도 된다)
print('{1} {0}'.format('one', 'two'))   # two one  (0부터 시작하니 순서가 바뀐다)
print('{0} {1}'.format(1, 2))           # 1 2  (숫자, 문자 섞어도 된다)

정렬과 채우기

{:정렬 칸수} 형태이고, 정렬 앞에 문자를 쓰면 그 문자로 빈 칸을 채운다.

형태의미
{:>10}10칸, 오른쪽 정렬
{:<10}10칸, 왼쪽 정렬
{:^10}10칸, 가운데 정렬
{:->20}20칸, 오른쪽 정렬, 빈칸은 -
{:+<10}10칸, 왼쪽 정렬, 빈칸은 +
print('%10s' % 'python')             # 오른쪽 정렬 (% 서식)
print('{:>10}'.format('python'))     # 같은 결과 (format)

print('%-10s' % 'python')            # 왼쪽 정렬
print('{:<10}'.format('python'))     # 같은 결과

print('{0:<10}'.format('die'))       # 왼쪽 정렬
print('{0:>10}'.format('hello'))     # 오른쪽 정렬
print('{0:^10}'.format('oasis'))     # 가운데 정렬

print('%20s' % 'script')
print('{0:->20}'.format('script'))   # 오른쪽 정렬, 여백을 -로 채우기
print('{0:+<10}'.format('script'))   # 왼쪽 정렬, 여백을 +로 채우기
print('{0:_<10}'.format('python'))   # 왼쪽 정렬, 여백을 _로 채우기
print('{0:.^10}'.format('python'))   # 가운데 정렬, 여백을 .으로 채우기

% 서식은 %가 따옴표 밖에 있고('%10s' % 'python'), format은 문자열 뒤에 .format()을 붙이는 구조다.

③ f-string

name = '홍길동'
age = 70
msg = f'나의 이름은 {name}입니다. 나이는 {age}입니다.'
print(msg)       # 나의 이름은 홍길동입니다. 나이는 70입니다.

문자열 앞에 f를 붙이고, { } 안에 변수나 식을 바로 쓴다. JS의 템플릿 리터럴(${name})과 거의 같은 역할이다.

같은 문장을 세 방식으로 비교해 보면 이렇다.

x = 10
y = 30
z = 'Lee'

# C 스타일 (서식 문자)
test1 = 'z=%s,sum=%d' % (z, (x + y))
print(test1)                                       # z=Lee,sum=40

# format 함수
test2 = 'z={z}, sum={sum}'.format(z=z, sum=(x + y))
print(test2)                                       # z=Lee, sum=40
# 0, 1 같은 번호가 아니라 이름을 쓰면 format 안에서 이름=값으로 지정해야 한다

# f-string
test3 = f'z={z},sum={x + y}'
print(test3)                                       # z=Lee,sum=40
# f가 이미 format을 뜻하므로 뒤에 .format()을 붙일 필요가 없다
방식모양특징
% 서식'%s %d' % (a, b)C 스타일. 값은 따옴표 뒤에 모아서 쓴다
format()'{} {}'.format(a, b)번호나 이름으로 지정
f-stringf'{a} {b}'변수와 식을 바로 쓴다. 가장 짧다

f-string에서 정렬

print(f"{'hello':<10}")     # hello     (hello 포함 10글자, 왼쪽 정렬)
print(f"{'hello':^10}")     #   hello   (10글자, 가운데 정렬)

n = 50
print(f'{n:^10}')           # 10칸에 n을 가운데 정렬

print(f'{n:@<20}')          # 20칸, 왼쪽 정렬, 빈칸은 @
print(f'{n:@>10}')          # 10칸, 오른쪽 정렬, 빈칸은 @

print(f'{n:-<10}')          # 10칸 확보, 빈칸을 -로 채우기 (왼쪽 정렬)
print(f'{n:#>20}')          # 20칸 확보, 빈칸을 #로 채우기 (오른쪽 정렬)

format에서 배운 :정렬칸수 규칙이 f-string에서도 그대로 쓰인다. 문자열은 따옴표 안에 따옴표가 들어가니 바깥을 큰따옴표로 감싼 것(f"{'hello':<10}")에 주의한다.


4. 리스트

Python에는 배열이 없다. 그 자리를 리스트가 대신한다.

리스트의 특징은 순서가 있고(o), 중복을 허용하고(o), 수정할 수 있고(o), 삭제할 수 있다(o).

선언

list1 = []
list2 = list()                 # []  (list 객체로 만든 빈 리스트)

print(list1, list2)            # [] []
print(type(list1), type(list2))   # <class 'list'> <class 'list'>

list3 = [60, 100, 98, 95]
list4 = [1000, 1000, 'Tom', 'Amy']
list5 = [1000, 1000, ['red', 'green', 'blue']]   # 리스트 안에 리스트를 넣을 수 있다
list6 = [3.42, 'python', 3, 1]                    # 자료형이 섞여도 된다
print(list3, list4, list5)

필기에는 list2 = list(1, 2)라고 하면 1, 2를 값으로 가진 리스트가 된다고 적혀 있었는데, 실제로는 list(1, 2)가 오류(list expected at most 1 argument, got 2)다. list()는 인자를 하나만 받고, 그 인자는 리스트나 튜플처럼 순회할 수 있는 것이어야 한다. 값 두 개로 리스트를 만들려면 list((1, 2))나 그냥 [1, 2]를 쓴다.

인덱싱

print(list3[0])                        # 60
print(list4[0] + list4[1] + list4[1])  # 3000  (같은 숫자 타입이라 더해진다)
print(list4[-1])                       # Amy  (뒤에서 첫 번째)
print(list5[-1][1])                    # green  (마지막 요소 ['red','green','blue']의 인덱스 1)

리스트 안에 리스트가 있으면 [ ][ ]로 겹쳐서 접근한다.

슬라이싱

print(list4[0:3])         # [1000, 1000, 'Tom']
print(list4[2:])          # ['Tom', 'Amy']  (인덱스 2부터 끝까지)
print(list5[2][1:3])      # ['green', 'blue']  (안쪽 리스트의 인덱스 1부터 3 미만)

문자열 슬라이싱과 똑같은 규칙이다.

연산

print(list3 + list4)      # 리스트 합치기
print(list3 * 3)          # list3을 3번 반복

# print(list3[0] + 'hi')  # 에러: 60은 문자열이 아니라서 더할 수 없다
print(str(list3[0]) + 'hi')   # 60hi  (str()로 형 변환)
print(list4[2] + 'hi')        # Tomhi  (이미 문자열이라 더할 수 있다)

JS에서는 60 + 'hi'가 알아서 '60hi'가 되었지만, Python은 숫자와 문자열을 +로 더하면 오류가 난다. 직접 str()로 바꿔야 한다. JS와 가장 크게 다른 부분 중 하나다.

수정

list3[0] = 4
print(list3)              # [4, 100, 98, 95]  (원래 60이었음. 원본이 바뀐다)

list3[1:2] = ['a', 'b', 'c']
print(list3)              # [4, 'a', 'b', 'c', 98, 95]
# list3[1:2] = [['a','b','c']] 처럼 한 겹 더 감싸면 리스트 안에 리스트가 들어간다

list3[1:2] = []           # 인덱스 1 구간을 빈 리스트로 바꾼다 = 삭제
print(list3)              # [4, 'b', 'c', 98, 95]

값을 대입해서 리스트를 수정할 수 있다. 슬라이스([1:2])에 대입하면 그 구간이 대입한 리스트의 요소로 통째로 바뀐다. 요소 하나를 여러 개로 늘릴 수도 있고, 빈 리스트를 대입해서 지울 수도 있다.

삭제: del

del list3[3]              # 인덱스 3의 값을 삭제
print(list3)              # [4, 'b', 'c', 95]  (98이 삭제됨)

중복

print(list4)              # [1000, 1000, 'Tom', 'Amy']

같은 값이 두 번 들어 있어도 그대로 출력된다. 리스트는 중복을 허용한다.


5. 리스트 메소드

오늘 교육에서 중요한 것으로 짚은 것은 f-string, format 함수, 리스트의 특징과 함수였다.

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

a.append(6)               # 인수를 리스트 끝에 추가 (원본 변경)
print(a)                  # [5, 3, 2, 4, 1, 6]

a.sort()                  # 오름차순 정렬 (원본 변경)
print(a)                  # [1, 2, 3, 4, 5, 6]

a.reverse()               # 거꾸로 정렬 (원본 변경)
print(a)                  # [6, 5, 4, 3, 2, 1]

print(a.index(5))         # 1  (5의 인덱스를 찾는다)

a.insert(2, 7)            # 인덱스 2에 7을 삽입 (원본 변경)
# 인덱스 2의 값을 바꾸는 게 아니라, 그 자리에 끼워 넣고 기존 값들은 뒤로 밀린다
print(a)                  # [6, 5, 7, 4, 3, 2, 1]

a.reverse()               # 다시 뒤집기 (원본 변경)
print(a)                  # [1, 2, 3, 4, 7, 5, 6]

a.remove(1)               # 괄호 안의 값을 삭제. 같은 값이 여러 개면 첫 번째 것만 삭제
print(a)                  # [2, 3, 4, 7, 5, 6]

a.pop()                   # 마지막 요소를 제거
print(a)                  # [2, 3, 4, 7, 5]

print(a.pop())            # 5  (pop은 제거한 값을 돌려준다)
print(a)                  # [2, 3, 4, 7]

print(a.count(4))         # 1  (4의 개수)
print(a.count(1))         # 0  (없으면 0)

ex1 = [8, 9]
a.extend(ex1)             # a 리스트 뒤에 ex1의 요소를 이어 붙인다
print(a)                  # [2, 3, 4, 7, 8, 9]
메소드동작원본
append(x)끝에 요소 추가변경
insert(i, x)인덱스 i에 x를 끼워 넣기변경
extend(리스트)끝에 다른 리스트의 요소를 이어 붙이기변경
remove(x)값 x를 찾아 삭제 (첫 번째만)변경
pop()마지막 요소 제거 (제거한 값을 반환)변경
sort()오름차순 정렬변경
reverse()순서 뒤집기변경
index(x)값 x의 인덱스 반환유지
count(x)값 x의 개수 반환유지

JS의 push, pop, sort, reverse와 같은 일을 하지만 이름과 쓰임이 다르다. push가 append, 맨 앞을 건드리는 unshift는 insert(0, x)에 해당한다.

한 가지 조심할 점이 있다. Python의 sort()와 reverse()는 원본만 바꾸고 None을 반환한다. Day.5에서 n = ary.sort()로 정렬된 배열을 받았던 JS와 달리, a = a.sort()라고 쓰면 a가 None이 되어 버린다.

실습 정리

li4 = [3, 3, 'Tom', 'Amy']
li5 = [1, 3, ['바나나', '사과', '파인애플']]

# li4의 마지막 값 출력
print(li4[3])             # Amy

# li5의 사과 출력
print(li5[2][1])          # 사과

# li4를 거꾸로 출력
li4.reverse()
print(li4)                # ['Amy', 'Tom', 3, 3]
# 같은 방식: print(li4[::-1])
# 처음과 끝을 비우면 전체이고, 증감이 -1이라 뒤에서부터 출력한다

a = 'abcdefg'
print(a[0:5:2])           # ace   (초기 인덱스 : 끝 인덱스(미만) : 증감)

li4.reverse()는 원본을 뒤집고, li4[::-1]은 원본은 그대로 두고 뒤집은 복사본을 만든다는 차이가 있다.


마무리

Python을 JS와 나란히 놓으면 비슷한 것, 다른 것, 없는 것이 구분된다.

  • 변수는 let, const 없이 x = 3으로 만들고, 불린은 True/False로 대문자로 시작한다.
  • Python에는 배열이 없고 리스트가 있으며, +로 숫자와 문자열을 더하면 오류가 난다.
  • 슬라이싱 [시작:끝:증감]은 끝이 "미만"이고, 음수 인덱스는 뒤에서부터 센다.
  • 출력 서식은 %, format(), f-string 세 가지가 있고, 정렬 규칙(:<10, :^10, :>10, 채울 문자)은 format과 f-string에서 같다.
  • 리스트 메소드는 대부분 원본을 바꾼다. sort()와 reverse()는 None을 반환한다.

Tags: Python 자료형 문자열 슬라이싱 f-string format 리스트 개발자 학습기록

profile
난 뭘까

0개의 댓글