Introducing Python(처음 시작하는 파이썬)
Chapter 2. 파이 재료: 숫자, 문자열, 변수
파이썬의 원자형 데이터 타입
1. Boolean
- \(\texttt{True}\) 혹은 \(\texttt{False}\)
2. Integer
- 정수형
3. Floating Number
- 실수형
4. String
- 문자열 (텍스트 문자들의 시퀀스)
2.1 변수, 이름, 객체
- Python에서는 모든 것(부울, 정수, 실수, 문자열, 자료 구조, 함수, 프로그램 등)이 Object(객체)로 구현되어 있다.
이런 점에서 Python은 언어 일관성을 제공한다고 할 수 있다.
- 파이썬은 객체의 타입을 변경할 수 없는 Strong Type 언어이다.
그 값이 Mutable*해도 데이터가 변경 가능한 것이지, 타입을 바꿀 수는 없다.
* Mutable(가변, 변수) : 값을 변경할 수 있는 타입을 의미한다.
* Immutable(불변, 상수) : 값을 변경할 수 없는 타입을 의미한다.
= 연산자
- 변수에 값을 할당(대입)하는 데 이용하는 연산자이다.
\(\texttt{type(Variable_or_Literal)}\)
- 변수 혹은 리터럴 값의 타입을 리턴하는 함수이다.
>>> a = 7
>>> b = a
>>> type(a)
<class 'int'>
>>> type(b)
<class 'int'>
>>> type(99.9)
<class 'float'>
>>> type('abc')
<class 'str'>
Python 변수 이름 명명 규칙
1. 변수 이름에는 알파벳 대, 소문자, 숫자, 언더스코어(_)만 사용할 수 있다.
2. 변수 이름은 숫자로 시작할 수 없다.
3. 언더스코어로 시작하는 변수 이름은 특별한 방법으로 처리된다.
4. 파이썬 Reserved Word(예약어)*로 지정되어 있는 이름들은 변수로 선언할 수 없다.
* Python Reserved Word
\(\texttt{False}\) | \(\texttt{None}\) | \(\texttt{True}\) | \(\texttt{and}\) | \(\texttt{as}\) | \(\texttt{assert}\) |
\(\texttt{break}\) | \(\texttt{class}\) | \(\texttt{continue}\) | \(\texttt{def}\) | \(\texttt{del}\) | \(\texttt{elif}\) |
\(\texttt{else}\) | \(\texttt{except}\) | \(\texttt{finally}\) | \(\texttt{for}\) | \(\texttt{from}\) | \(\texttt{global}\) |
\(\texttt{if}\) | \(\texttt{import}\) | \(\texttt{in}\) | \(\texttt{is}\) | \(\texttt{lambda}\) | \(\texttt{nonlocal}\) |
\(\texttt{not}\) | \(\texttt{or}\) | \(\texttt{pass}\) | \(\texttt{or}\) | \(\texttt{pass}\) | \(\texttt{raise}\) |
\(\texttt{return}\) | \(\texttt{try}\) | \(\texttt{while}\) | \(\texttt{with}\) | \(\texttt{yield}\) |
Python class
- 객체의 정의를 의미한다.
- Python에서 "class"와 "type"의 의미는 거의 동일하다.
2.2 Numbers (숫자)
파이썬의 산술 연산자
Operator | Meaning | Example | Output |
\(\texttt{+}\) | 덧셈 | 5 + 8 | 13 |
\(\texttt{-}\) | 뺄셈 | 90 - 10 | 80 |
\(\texttt{*}\) | 곱셈 | 4 * 7 | 28 |
\(\texttt{/}\) | 부동소수점 나누기 | 7 / 2 | 3.5 |
\(\texttt{//}\) | 정수 나누기 (몫 구하기) | 7 // 2 | 3 |
\(\texttt{%}\) | Mod (나머지 구하기) | 7 % 3 | 1 |
\(\texttt{**}\) | 지수 | 3 ** 4 | 81 |
\(\texttt{+=}\) \(\texttt{-=}\) \(\texttt{*=}\) \(\texttt{/=}\) \(\texttt{//=}\) |
복합 대입 연산자 |
2.2.1 Integers (정수)
- 대화식 인터프리터에서는 연속된 숫자를 Literal 정수로 간주한다.
- 0을 다른 숫자 앞에 넣을 수 없다.
>>> 05
File "<stdin>", line 1
05
^
SyntaxError: leading zeros in decimal integer literals are not permitted; use an 0o prefix for octal integers
- 파이썬에서는 수치값과 연산자 사이의 공백의 개수에 상관없이 계산을 수행한다.
(즉, \(\texttt{2+8}\) 과 \(\texttt{2 + 8}\) 의 결과는 같다.)
- Divisor(제수)와 Dividend(피제수) 모두 정수이더라도 \(\texttt{/}\) 연산자로 나누면 결과는 부동소수점 수가 리턴된다.
- 제수가 0이면 Exception*이 발생된다.
\(\texttt{divmod(n, m)}\)
- n ÷ m 의 결과를 (몫, 나머지) 형태의 Tuple로 리턴하는 함수이다.
※ Python에서는 다수의 데이터 리턴이 가능하다.
* Exception(예외) : Python에서의 프로그램 에러 처리 방식이다.
2.2.2 Precedence (우선순위)
Operator | Meaning and Example |
[v1 , ...] {v1 , ...} {k1 : v1, ...} (...) |
List creation or comprehension Set creation or comprehension Dictionary creation or comprehension Generator creation or comprehension Parenthesized expression |
seq[n] seq[n : m] func(args ...) obj.attr |
Index Slice Function call Attribute reference |
** | Exponentiation |
+var -var ~var |
Positive Negative Bitwise NOT |
* / // % |
Multiplication Float division Int division Remainder |
+ - |
Addition Substraction |
<< >> |
Bitwise Left Shifts Bitwise Right Shifts |
& | Bitwise AND |
| | Bitwise OR |
in not in is is not < <= > >= != == |
Membership & Equality tests |
not x | Boolean NOT |
and | Boolean AND |
or | Boolean OR |
if ... else | Conditional expression |
lambda | lambda expression |
- 같은 칸에 있는 연산자는 같은 우선순위를 가진다.
※ 연산자 우선순위에 의거하여 코드를 작성하기 보단, 소괄호를 이용하여 연산을 기술하면 보다 읽기 쉬운 코드가 된다.
2.2.3 Bases (진수)
- Python에서 Base(진수)의 기본값은 10진수이다.
- Python에서는 아래와 같은 접두어로 리터럴 상수에 진법을 표현할 수 있다.
1. Binary Litera : \(\texttt{0b, 0B}\)
2. Octal Literal: \(\texttt{0o, 0O}\)
3. Hexa Decimal Literal: \(\texttt{0x, 0X}\)
(Python 인터프리터는 다른 진법 체계의 수를 자동으로 10진수로 변환해 출력한다.)
2.2.4 Type Conversions (형변환)
\(\texttt{int(data)}\)
- data를 정수형으로 변환한 값을 리턴한다.
- 숫자로 이루어진 문자열을 정수로 반환하며, 소수점 혹은 지수를 포함하는 문자열은 소수부를 Chopping하여 출력한다.
- 숫자가 아닌 데이터에 대한 변환을 시도하면 Exception이 발생한다.
\(\texttt{float(data)}\)
- data를 부동소수점형으로 변환한 값을 리턴한다.
- 유효한 부동소수점수의 문자열(숫자, 기호, 소수점, 지수)을 부동소수점수로 변환할 수도 있다.
(Python은 Strong Type 언어임을 상기하자. 한 번 정해진 변수의 타입은 변하지 않는다.)
- Python 3부터는 \(\texttt{long}\) 타입이 사라지고, \(\texttt{int}\)의 크기가 유연해졌다.
(\(\texttt{int}\)의 크기는 64Bit을 넘어설 수도 있으며, googol(=\(10^{100}\))도 저장할 수 있다.
2.2.5 int의 크기
Python 2에서의 \(\texttt{int}\)와 \(\texttt{long}\)
- Python 2에서 int는 32bits, long은 64bits로 제한된다.
Python 3에서의 데이터 크기
- Python 3에서는 long 타입이 사라지고, int의 크기를 유연하게 하는 것으로 대체했다.
- Python 3에서의 int 타입은 64bits이상의 크기도 가질 수 있다.
* 심지어 Googol(\(10^{100}\))과 같은 큰 수도 다룰 수 있다.
2.2.6 Floats (부동소수점수)
- float 변수 또한 int와 같이 +, -, *, /, //, **, %, divmod() 연산이 가능하다.
float(data)
- data를 부동소수점수로 변환한다.
2.2.7 Math Functions (수학 함수)
- Appendix C: Py Sci pp.469-492.
2.3 문자열
- Python 3에서는 Unicode 문자 체계 하에 전 세계의 많은 언어들을 다룰 수 있다.
- 파이썬에서 문자열은 Immutable(불변)하므로, 문자열 자체를 변경할 수는 없다.
2.3.1 Create with Quotes (인용 부호로 문자열 생성)
- Single Quotation(' ') 혹은 Double Quotation(" ")으로 문자열을 생성할 수 있으며, 두 기호 간 차이는 없다.
- 대화식 인터프리터에서 문자열을 출력하면, 문자열이 기본적으로 Single Quotation으로 둘러싸여 출력된다.
- 두 가지 종류의 인용 부호를 유지하는 이유는 인용 부호가 포함된 문자열을 만들기 위해서이다.
ex) 'AB"CD' -> AB"CD / "AC'D'F" -> AC'D'F
- 3개의 Single Quotation안에 여러 줄이 있는 경우, 문자열 끝에 들어있는 라인 끝 문자(개행 문자)가 보존되며,
양쪽 끝에 공백이 있는 경우에도 보존된다.
base = '' // string base; 유사한 구문
// 빈 문자열로 초기화하는 방식으로 문자열 변수를 명시적으로 선언한다.
base += 'current inventory'
base += ': bottles'
2.3.2 Convert Data Types by Using \(\texttt{str()}\) (데이터 타입 변환: \(\texttt{str()}\))
\(\texttt{str(data)}\)
- data를 문자열로 변환한 값을 리턴한다.
- 문자열이 아닌 객체를 \(\texttt{print()}\)로 호출할 때, 파이썬에서는 내부적으로 \(\texttt{str()}\)을 호출한다.
- 변수나 상수를 문자열 안에 삽입하는 String Interpolation(문자열 보간)시에도 내부적으로 \(\texttt{str()}\)이 호출된다.
2.3.3 Escape Character (이스케이프 문자)
- Python에서는 백 슬래시(\) 기호를 통해 문자열 내에서 특수한 의미를 표현할 수 있다.
\n | 개행 문자 | \t | 탭 문자 | \\ | 백 슬래시 |
\' | 작은 따옴표 | \" | 큰 따옴표 |
2.3.4 Combine with + (결합: +)
- + 연산자를 사용하여 리터럴 문자열, 문자열 변수를 서로 결합할 수 있다.
- \(\texttt{print()}\) 함수는 여러 문자열을 Argument로 받아 출력할 시, 문자열 사이에 공백을 넣으며, 마지막에는 줄 바꿈 문자를 붙여 출력한다.
2.3.5 Duplicate with * (복제하기: *)
- * 연산자를 사용하여 문자열을 일정 횟수 반복하여 리턴할 수 있다.
- 피연산자는 String * Constant 타입이어야 한다.
>>> start = 'Na' * 4 + '\n'
>>> print(start)
NaNaNaNa
2.3.6 Extract a Character with [ ] (문자 추출: [ ])
- \(\texttt{[]}\) 연산자를 통해 문자열 내에서 한 문자를 추출할 수 있다.
- 대괄호 안에는 해당 문자의 오프셋이 입력된다.
- 음수 인덱스는 문자열 뒤에서 부터의 오프셋을 의미한다.
- 문자열은 Immutable하므로, [ ] 연산자를 통해 문자를 삽입/수정할 수 없고, 함수를 통해야 한다.
letters = 'abcdefghijklmnopqrstuvwxyz'
letters[0] # 'a'
letters[1] # 'b'
letters[-1] # 'z'
letters[-2] # 'y'
2.3.7 Slice with [start : end : step] (슬라이스: [start : end : step])
- 한 문자열에서 Substring을 추출하는 방법이다.
- start는 시작 오프셋, end는 끝 오프셋, step은 옵션을 의미한다.
- 시작 오프셋의 Default는 0이며, 끝 오프셋의 Default는 마지막 문자 위치이다.
※ end값은 실제 Array 오프셋 + 1의 값으로 표현된다.
ex) \(\texttt{Array[ : 21] }\) \(\iff\) \(\texttt{Array[0]}\)부터 \(\texttt{Array[20]}\)까지의 문자들을 추출한다.
\(\texttt{[:]}\)
- 처음부터 끝까지 전체 시퀀스를 추출한다.
\(\texttt{[start:]}\)
- start 오프셋부터 끝까지 시퀀스를 추출한다.
\(\texttt{[:end]}\)
- 처음부터 (end-1) 오프셋까지의 시퀀스를 추출한다.
\(\texttt{[start:end:step]}\)
- step수만큼 문자를 건너뛰면서, start 오프셋부터 (end-1) 오프셋까지 시퀀스를 추출한다.
- step을 음수로 지정해서 백스텝 기능을 이용할 수 있다.
2.3.8 Get Length with len() (문자열 길이: len())
\(\texttt{len(string)}\)
- string의 길이를 리턴한다.
2.3.9 Split with split() (문자열 나누기: split())
\(\texttt{string.split(delimiter)}\)
- Delimiter(구분자)를 기준으로 하나의 문자열 string을 작은 문자열들의 List로 리턴한다.
- Delimiter의 Default는 공백 문자이다.
- Delimiter가 연속된 문자열의 경우, Delimiter 사이사이에 empty list가 존재하는 것으로 간주한다.)
2.3.10 Combine with join() (문자열로 결합하기: join())
\(\texttt{string.join(list)}\)
- 문자열 list들 사이에 string을 삽입한 하나의 문자열을 리턴한다.
2.3.11 Playing with Strings (문자열 다루기)
\(\texttt{A.startswitch(B)}\)
- A가 B로 시작하는지에 대한 여부를 Boolean Type으로 리턴한다.
\(\texttt{A.endswitch(B)}\)
- A가 B로 끝나는지에 대한 여부를 Boolean Type으로 리턴한다.
\(\texttt{A.find(B)}\)
- A에서 첫 번째로 B가 나오는 오프셋(인덱스 + 1)을 리턴한다.
- 인덱스가 아닌, 오프셋 값을 출력한다. (즉, index + 1에 해당되는 값이 출력된다.)
\(\texttt{A.rfind(B)}\)
- A에서 마지막으로 B가 나오는 오프셋(인덱스 + 1)을 리턴한다.
\(\texttt{A.count(B)}\)
- A에서 B가 나타나는 횟수를 리턴한다.
\(\texttt{A.isalnum(B)}\)
- A가 글자와 숫자로만 이루어졌는지에 대한 여부를 Boolean Type으로 리턴한다.
2.3.12 Case and Alignment (대소문자와 배치)
\(\texttt{A.strip(B)}\)
- A의 양 끝에 B 시퀀스를 삭제한 문자열을 리턴한다.
>>> EX = 'aabbccaaa'
>>> EX.strip('a')
'bbcc'
\(\texttt{A.capitalize()}\)
- A의 첫 번째 단어를 대문자로 만든 문자열을 리턴한다.
\(\texttt{A.title()}\)
- A의 모든 단어의 첫 글자를 대문자로 만든 문자열을 리턴한다.
\(\texttt{A.upper()}\)
- A의 모든 글자를 대문자로 만든 문자열을 리턴한다.
\(\texttt{A.lower()}\)
- A의 모든 글자를 소문자로 만든 문자열을 리턴한다.
\(\texttt{A.swapcase()}\)
- A의 글자들 중 대문자는 소문자로, 소문자는 대문자로 Toggle시켜 만든 문자열을 리턴한다.
\(\texttt{A.center(n)}\)
- A를 n만큼의 공간에 중앙에 배치한 문자열을 리턴한다.
\(\texttt{A.ljust(n)}\)
- A를 n만큼의 공간에 왼쪽 정렬한 문자열을 리턴한다.
\(\texttt{A.rjust(n)}\)
- A를 n만큼의 공간에 오른쪽 정렬한 문자열을 리턴한다.
2.3.13 Substitute with replace() (대체하기: replace())
\(\texttt{A.replace(Origin, New, Reps)}\)
- A 내부의 Origin 문자열을 New로 대체한다.
- 이 때 Reps만큼의 횟수가 진행되는데, Reps가 생략되면 문자열 A의 모든 범위에서 조건에 맞게 대체된다.
- 대체하고자 하는 문자열을 정확히 아는 상태에서 사용하기 용이하다.
2.3.14 문자열 함수
- 참조 (URL)
2.4 Things to Do (연습문제)
2.1 1시간은 몇 초인가? 대화식 인터프리터를 사용해서 계산해보라. 1시간은 60분이고, 1분은 60초다. 이 둘을 곱한다.
Sol 2.1
>>> 60 * 60
3600
2.2 계산한 결과를 seconds_per_hour 변수에 저장하라.
Sol 2.2
>>> seconds_per_hour = 60 * 60
>>> seconds_per_hour
3600
2.3 1일은 몇 초 인가? seconds_per_hour 변수를 사용하라.
Sol 2.3
>>> seconds_per_hour * 24
86400
2.4 계산한 결과를 seconds_per_day 변수에 저장하라.
Sol 2.4
>>> seconds_per_day = seconds_per_hour * 24
>>> seconds_per_day
86400
2.5 부동소수점(/) 나눗셈을 사용해서 seconds_per_day를 seconds_per_hour로 나누어라.
Sol 2.5
>>> seconds_per_day / seconds_per_hour
24.0
2.6 정수(//) 나눗셈을 사용해서 seconds_per_day를 seconds_per_hour로 나누어라.
이전 문제의 부동소수점 결과에서 본 .0이 있는가?
Sol 2.6
>>> seconds_per_day // seconds_per_hour
24
정수 나눗셈은 계산 결과에서 소수부를 Choppoing하기 때문에 소수부는 출력(반환)되지 않는다.
Reference: Introducing Python(처음 시작하는 파이썬) (Bill Lubanovic 저, O'Reilly, 2015)