Chapter 1. 기본자료형과 변수#

이 장에서는 기본 자료형(정수형, 실수형, 문자열)과 변수, 그리고 산술연산자를 이용하여 수식을 표현하는 방법을 알아본다.

학습목표와 기대효과

  • 학습목표

    • 기본자료형을 알아보자.

    • 산술연산자를 이용하여 수식을 표현해보자.

    • 숫자, 문자 데이터를 변수에 저장해보자.

  • 기대효과

    • 파이썬으로 산술연산을 위한 표현식을 작성할 수 있다.

    • 정수, 실수, 문자열 자료 저장을 위한 변수의 개념을 이해할 수 있다.

기본 자료형#

파이썬은 다양한 데이터 타입(자료형, Data Type)을 지원하고 있다. 데이터 타입은 데이터가 가지고 있는 속성을 의미하며, 데이터 타입에 따라 지원하는 연산이 다르다. 파이썬이 지원하는 몇 가지 주요 데이터 타입을 알아보고, 그에 따른 연산식을 표현해보자.

  • 숫자형 데이터

    • 정수형(int)

    • 실수형(float)

  • 문자열(str)

  • 불(bool): 논리형으로, True 또는 False를 가진다.

  • None: 값이 없음을 의미하며, ‘아무것도 반환하지 않은’ 함수의 반환 값이다.

Tip

다른 프로그래밍 언어에서는 실수형에 float과 double형이 존재하지만 파이썬에서는 double형은 따로 존재하지 않는다.

또한 문자(char)와 문자열(string)을 따로 분류하고 있지만, 파이썬에서는 문자 길이에 상관 없이 문자열로 다루고 있다.

숫자 데이터#

정수형 데이터#

정수형 데이터는 0을 포함한 자연수이다. 예를들어, …, -100, -10, 0, 1, 10, 100, … 등이 정수형 데이터이다.

Tip

python에서는 정수데이타를 표현할 수 있는 범위의 한계는 없다. 즉, 엄청 큰 양의 정수, 엄청 작은 음의 정수를 버림없이 표현이 가능하다.

엄청 큰 혹은 엄청 작은 수를 코드셀에 적고 실행시켜보자. 코드를 실행하는 방법은 앞 장에서도 설명했 듯이, 코드셀 앞에 실행버튼을 눌러도 되고, 단축키를 사용해도 된다.

  • Ctrl + Enter : 코드셀 실행 후 커서는 방금 실행한 셀에 있다.

  • Shift + Enter : 코드셀 실행 후 커서가 다음 셀로 넘어간다. 다음 셀이 없을 경우, 새로운 셀이 만들어진다.

셀을 실행을 시키면 해당 셀 아래에 결과가 출력된다.

123456789012345678901234567890 * 1234556677
152414403196171593319617159331809301530
4434567788884344431667886553 - 3354565631156734333583729667788999900
-3354565626722166544699385236121113347

실수형 데이터#

실수형 데이터는 소수점을 가진 수로 -5.432, 0.0, 5.0, 9.5, … 등이 실수형 데이터이다.

컴퓨터에서 실수를 표현하는 방법은 정수에 비해 훨씬 복잡하다.

실수를 표현하는 방법은 고정된 자릿수의 소수를 표현하는 고정소수점 방식과, 소수점의 위치를 고정하지 않는 부동소수점 방식이 있다.

그러나 고정소수점 방식은 제한된 자릿수로 인해 표현할 수 있는 범위가 매우 작아 컴퓨터에서는 일반적으로 부동소수점 방식을 이용한다. 부동소수점 방식은 실수를 표현할 때 지수부와 가수부로 나누는데, 아래의 수식을 이용하여 매우 큰 실수까지도 표현할 수 있다.

\( ±(1.가수부)×2^{(지수부-127)} \)

실수형(부동소수점) 데이터 표기법

컴퓨터에서 표준화된 실수형 데이터 표기법은 크게 두 가지가 있다.

첫 번째는 0.12, 1.12345678 등과 같이 우리가 흔히 아는 소수점 표현 방식이다. 실수의 경우 표현할 수 있는 유효한 자리수의 한계가 존재한다. 파이썬에서의 소수점 표현 방식의 유효한 자리수의 한계는 소수점 16자리이다.

  • 소수점 표현 방식의 유효한 자리수 한계를 확인해보자. 소수점 17자리에서 반올림되어 소수점 16자리까지 표현되는 것을 확인할 수 있다.

1.12345678901234567890123456789
1.1234567890123457

실수형(부동소수점) 데이터 표기법

두 번째는 지수 표현 방식이다. 지수(Exponential)는 로마자 E 또는 e로 표기하는데 과학이나 공학에서 아주 큰 숫자를 간단하게 표기할 때 사용하며, 의미는 10^이다. 예를들어, 지수 표현 방식으로 1.23e+5은 \(1.23 * 10^5\)이며, 123000.0과 같다. 1.23e-4는 \(1.23 * 10^{-4}\)이며 0.000123과 같다.

1.23e+5
123000.0
1.23e-4
0.000123
  • 지수 표현 방식도 유효한 자리수의 한계가 있다. 예를 들어, \(1.23 * 10^{308}\)은 지수표현 방식으로 표현이 가능하다.

  • \(1.23 * 10^{309}\)의 경우 지수 표현 방식에서 유효한 자리수의 한계를 넘어가서 inf(infinity)로 나온다.

1.23e+308
1.23e+308
1.23e+309
inf

부동소수점 방식의 한계

부동 소수점 방식은 유효한 자리수의 한계로 실수를 표현하는데 오차가 발생한다. 그 이유는 위에서 언급한 수식때문이다. 이 수식을 사용하면 표현할 수 있는 범위는 늘어나지만, 10진수를 정확하게 표현할 수는 없게 된다.

예를 들어, 0.1 + 0.2를 계산하면 0.30000000000000004로 0.3과 같은지를 확인하면 False가 나온다.

컴퓨터에서는 숫자를 비트로 표현하는데 예를 들어, 1부터 10까지 정수는 10개지만 실수는 무한히 많다. 무수히 많은 실수를 유한개의 비트로 정확하게 표현할 수가 없다. 따라서 실수는 유한개의 비트를 사용하여 근사치를 표현한다. 즉, 0.30000000000000004는 0.3을 표현한 근사치이다. 일반적으로 두 수가 같은 실수라는 것을 판단하기 위해 머신 엡실론(machine epsilon)을 기준으로 한다.

a = 0.1+0.2
print(a)
0.30000000000000004
a == 0.3
False

숫자형 연산자(Numeric operators)#

정수형, 실수형 데이터는 다음과 같은 산술연산자를 사용하여 연산이 가능하다.

연산 기호

의미

예시

실행 결과

+

덧셈(Addition)

2 + 2

4

-

뺄셈(Subtraction)

2.0 - 2.0

0.0

*

곱셈(Multiplication)

2 * 3

6

/

나눗셈(Division)

6 / 3

2.0

//

버림나눗셈,몫(Floor division)

10 // 2

5

%

나머지(Remainder)

3 % 2

1

**

제곱(Square)

2 ** 3

8

참고

정수값으로 연산을 하면 그 결과는 정수형으로 나오고, 실수값으로 연산을 하면 그 결과는 실수형으로 나온다. 그러나 나눗셈(Division) 연산의 경우 정수값, 실수값 관계없이 항상 그 결과는 실수형으로 나온다.

주의

  • 파이썬에서는 대괄호[ ]는 리스트(list), 중괄호{ }는 셋(set)의 의미를 갖고 있으므로 수식을 묶을 때에는 소괄호( )만 사용할 수 있다.

  • 제곱연산자의 경우 ^로 표기하지 않도록 주의하자.

연산자가 손에 익히도록 아래의 수식을 코드로 작성해보자.

😄문제1. 몫 구하기

50 나누기 4의 몫을 구하시오.

😄문제2. 나머지 구하기

50 나누기 4의 나머지를 구하시오.

😄문제3. 수식을 코드로 표현해보기

\( 5^2*10÷4 \)

😄문제4. 수식을 코드로 표현해보기

\(\frac {10.5 + 2 × 3} {45-3.5}\)

문자열 데이터#

문자열은 텍스트의 묶음으로 홑 따옴표, 쌍 따옴표, 트리플 따옴표로 묶어준다. 즉 코드에서 이들 기호를 만나면 문자열의 시작 또는 끝을 나타내는 기호로 인식한다. 문자열이 한줄인 경우에는 홑 따옴표, 쌍 따옴표, 트리플 따옴표 구분없이 사용 가능하다. 문자열이 여러줄인 경우, 이를 멀티라인 스트링(multi-line string)이라 부르는데, 이때에는 트리플 따옴표만 사용 가능하다.

  • 문자열을 작성해보자. 홑 따옴표를 포함한 문자열이 출력된다.

'hi'
'hi'
  • 이번에는 print()에 문자열을 넣어서 작성해보자. print()는 다음 장에서 설명하겠지만 문자열 또는 연산의 결과를 화면에 출력하는 함수이다.

print('hello')
hello
print("Hello World")
Hello World
print('파이썬은 재밌어')
파이썬은 재밌어
  • 멀티라인 스트링인 경우, print()를 쓰지 않고 출력하는 것과 print()에 문자열을 넣어서 출력하는 것의 차이를 뚜렷하게 확인할 수 있다.

  • print()를 쓰지 않고 출력하면 눈에 보이지 않았던 줄바꿈기호 \n가 포함되어 한줄로 출력된다.

"""안녕
반가워
파이썬
"""
'안녕\n반가워\n파이썬\n'
  • print()에 문자열을 넣어서 출력한 결과는 줄바꿈기호를 줄바꿈으로 인식하여 출력한다.

print("""안녕
반가워
파이썬
""")
안녕
반가워
파이썬
  • 문자열은 문자뿐만 아니라 공백, 숫자, 특수문자를 포함할 수 있다.

print('7 apples, 14 oranges, 3 lemons')
7 apples, 14 oranges, 3 lemons
print('O*&#wY%*&OCfsdYO*& gfC%YO')
O*&#wY%*&OCfsdYO*& gfC%YO
  • 홑따옴표(‘)나 쌍따옴표(“)기호를 출력해야 할 때가 있다. 이럴때는 상반된 기호로 써준다.

print('그녀는 "블랙홀"이라고 말했어!')
그녀는 "블랙홀"이라고 말했어!
print("그녀는 '블랙홀'이라고 생각했어!")
그녀는 '블랙홀'이라고 생각했어!
  • 홑따옴표(‘)나 쌍따옴표(“)기호가 모두 들어가 있을 때에는 고민할 필요없이 멀티라인 스트링으로 써준다.

print('''그녀는 '블랙홀'이라고 생각하면서 "충치가 깊네요." 라고 말했다.''' )
그녀는 '블랙홀'이라고 생각하면서 "충치가 깊네요." 라고 말했다.

f-string#

f-string은 문자열 포맷팅(string formatting)이다. 문자열 앞에 f를 붙이면 값을 넣어서 문자열을 만들 수 있다.

name = "민지"
age = 20
f'{name}{age}살이야'
'민지는 20살이야'
a = 5
b = 10
f'Five plus ten is {a + b} and not {2 * (a + b)}.'
'Five plus ten is 15 and not 30.'

문자열 연산자(String operators)#

문자열도 +, * 연산자를 사용하는 것이 가능하다. 단, 문자열에서 +연산자는 문자열의 나열을 의미하며, *연산자는 문자열의 반복을 의미한다.

연산 기호

의미

예시

실행 결과

+

덧셈(Addition)

'hello' + 'world'

helloworld

*

곱셈(Multiplication)

'hello' * 3

hellohellohello

print('파이썬은' + ' ' + '즐거워! ')
파이썬은 즐거워! 
print( '파이썬은 즐거워! ' * 3 )
파이썬은 즐거워! 파이썬은 즐거워! 파이썬은 즐거워! 

참고

print( '파이썬은 즐거워! ' * 3 )

문자열과 정수형 데이터에 곱셈(*) 연산자를 사용하였을 때 에러가 발생하지 않고 문자열이 정수값만큼 반복된다는 것을 확인했다.

그렇다면 덧셈(+) 연산도 가능할까?

print( 'hello!' + 5 )

결론은 문자열과 숫자 데이터 간 덧셈연산은 지원하지 않아 에러가 나온다.

변수(Variable)#

숫자가 숫자로만 존재하거나, 문자가 문자로만 남아있다면 활용성이 떨어진다. 프로그래밍에서는 숫자, 문자 등의 값(value)를 변수에 저장해 놓으면 훨씬 활용성을 높일 수 있다.

변수란 값을 저장하기 위한 이름을 가진 저장공간이며, 대입 연산자 기호인 =를 이용하여 값을 저장한다.

r = 10
pi = 3.14
S = pi * (r**2)
print(f'반지름 {r}의 원의 넓이는 {S}입니다.')
반지름 10의 원의 넓이는 314.0입니다.

변수는 필요한 만큼 여러개를 만들어 사용할 수 있다. 단 변수명을 지을때는 몇 가지 규칙이 있다.

변수명 짓는 규칙#

  • 대소문자를 서로 다른 변수로 구별한다.

  • 문자, 숫자, _(under bar)로 이루어진다.

  • 변수명에 공백이 들어갈 수 없다.

  • 숫자로 시작할 수 없다.

  • 예약어는 사용할 수 없다.

예약어란 파이썬에서 내장되어 이미 사용하기로 정의된 키워드를 의미한다. 참고로 아래 코드를 통해 파이썬의 예약어와 개수를 확인해보자.

import keyword
print(keyword.kwlist)
print(len(keyword.kwlist))
['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
35

Vaild names

myvar = "Byun"
my_var = "Byun"
_my_var = "Byun"
myVar = "Byun"
MYVAR = "Byun"
myvar2 = "Byun"

Invaild names

2myvar = "Byun" #숫자로 시작할 수 없다.
my-var = "Byun" #_이외의 특수문자가 들어갈 수 없다.
my var = "Byun" # 공백이 들어갈 수 없다.
if = "Byun" #예약어는 사용할 수 없다.

파이썬에는 미리 기능을 만들어 놓은 내장함수, 클래스가 매우 많다.(예, print(), input(), str(), int(), …)

내장함수명이나 클래스명을 변수명으로 사용하지 말자. 미리 정의되어 있는 내장함수명이나 클래스명을 변수명으로 사용하면 원래 정의된 기능이 제 기능을 하지 못한다. 예를들어 아래와 같이 작성하면 기존에 정의된 기능이 동작하지 않게 된다.

  • print=’hello’

  • input=input()

  • str=’hello’

내장함수명, 클래스명을 변수명으로 만들어 실행시켰다면!

내장함수명, 클래스명을 변수명 만들어 실행시켰다면 당황하지 말고,

  • 메뉴 런타임 >> 런타임 다시 시작을 하면 된다.

  • 런타임 다시 시작은 모든 로컬 변수를 포함한 런타임 상태가 삭제됩니다.라는 경고 문구와 같이 현재 만들어 놓은 변수 등을 초기화 시킨다는 의미이다.

  • 따라서 올바르지 않은 변수명도 초기화 되어 기존의 내장함수나 클래스의 기능이 원래대로 복구된다.

  • 그런 다음 문제를 일으킨 변수명은 바로 삭제하자.

한글 변수명도 가능할까?

물론, 한글 변수명도 가능하다. 한글 변수명을 사용하라고 말하고 싶지만 해외 운영체제의 경우 한글이 깨질 수 있으므로 가급적 영문변수명 사용을 권장한다.

다음에서 변수명으로 사용할 수 있는 것을 모두 골라보자.

  1. sum

  2. _count

  3. 2nd_base

  4. money$

  5. True

  6. King3

변수에 데이터 저장하기#

변수에 값을 저장해보자. 이를 프로그래밍에서는 변수에 값을 할당한다라고 말한다. 변수에 값을 할당하려면 대입연산자 기호인 =를 기준으로 왼쪽에는 변수명, 오른쪽에는 값 또는 표현식을 적는다.

아래 코드를 설명해보면,

  • 변수 num에 정수 10000을 저장한다.

  • 변수 won에 문자열 ‘원!’를 저장한다.

  • 변수 num과 won을 활용하여 문자열을 출력한다.

  • 변수에는 숫자, 문자열 모두 저장할 수 있다.

num = 10000
won = '원!'
print(num, won, '입니다.')
print(f'{num}{won} 입니다.')
10000 원! 입니다.
10000원! 입니다.

변수와 객체(object)

변수에 값을 저장하면 실제 컴퓨터에서는 어떻게 동작할까? 예를들어, 변수 num에 100을 저장했다면 100이라는 값이 메모리에 할당되는데 이를 객체라고 한다.

객체는 id, value, type을 갖고 있다. id는 메모리상에서의 객체의 주소이며, value는 메모리에 저장된 객체가 가지고 있는 값, type은 객체가 지원하는 연산을 정의하고 있는 객체의 타입을 의미한다. 그리고 변수가 그 객체를 가르킨다.

변수 역시 메모리의 어딘가에 할당되는 공간인데, 그 공간에는 객체의 메모리 주소가 저장된다. 즉, 변수 num의 공간에는 100이 저장되어 있는 객체의 메모리 주소가 저장되어 있고, 변수를 통해 실제 객체에 접근할 수 있게 된다.

주의!

초보자의 경우, 변수명과 문자열에 익숙하지 않아 변수명에 문자열 처리를 하여 출력을 하는 실수를 범하기도 한다.

만약 아래와 같이 코드를 작성했다면, 변수 name에 저장되어 있는 ‘sun’이 출력되는 것이 아니라 ‘name’이라는 문자열 자체가 출력된다. 변수 name과 문자열 ‘name’은 서로 다르다는 것에 주의하자.

name = 'sun'
print('name')
name
  • 변수 name에 문자열 ‘young’을 저장한다.

  • 변수 name의 값을 출력해보면 young이 출력된다. 이제 이와 같은 코드는 이미 이해하고 있을 것이다.

  • But!! 여러분은 방금 변수의 중요한 특징 하나를 경험했다. 변수는 새로운 값을 저장하면 이전에 저장했던 값은 사라진다. 정확히 말하자면 변수가 가르키던 객체가 달라진다.

  • 즉, 변수 name은 ‘sun’ 대신에 ‘young’을 가르키게 된다.

name = "young"
print(name)
young
  • 변수 spam에 100을 저장한다.

  • 변수 spam에 200을 더해서 출력한다. 결과는 300이 출력된다.

  • 현재 변수 spam에는 어떤 값이 저장되어 있을까? 당연히 100이 저장되어 있다. 우리는 spam+200의 결과를 변수 spam에 저장한 것이 아니므로 변수 spam의 값은 변화가 없다.

spam = 100
print(spam+200)
300
  • 이번에는 이와 같이 코드를 작성했다면 변수 spam에 저장되어 있는 값은 무엇일까?

  • spam = spam + 5에서 연산식은 어떤 순서로 실행될까? 대입연산자(=)가 쓰인 코드의 순서는 항상 = 기호 오른쪽의 연산을 먼저 실행한 후, 그 결과를 = 기호 왼쪽의 변수에 저장한다. 따라서 spam + 5의 연산을 먼저 실행하고 그 결과를 대입연산자 왼쪽에 있는 변수 spam에 저장한다.

  • 결과 20이 출력된다.

spam = 15
spam = spam + 5
print(spam)
20

주의

print(spam = spam + 5)

위와 같이 코드를 작성하지 않도록 하자. print() 함수는 대입연산식을 수행할 수 없다.

  • 코딩을 하다보면 에러를 자주 마주치게 된다. 에러를 두려워하지 말자. 에러메시지는 여러분에게 많은 정보를 알려준다.

  • 아래 코드의 에러는 NameError로 주로 변수명을 정의하지 않고 사용하였을 때 발생한다.

  • 변수에 오타가 있을때도 만나게 되는데, 변수 eggs를 정의해놓고 라인 3에서는 eggz로 사용하였다. 따라서 eggz를 정의하지 않아서 발생한 경우이다.

eggs = 20
fizz = 10
spam = fizz + eggz
spam
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-1-ba8dae9bd2c7> in <cell line: 3>()
      1 eggs = 20
      2 fizz = 10
----> 3 spam = fizz + eggz
      4 spam

NameError: name 'eggz' is not defined
  • 아래 코드에서는 변수 fizz, eggs를 정의하지 않고 사용하였는데 에러가 나오지 않는다. 그 이유는 무엇일까? 우리는 이미 앞에서 fizz와 eggs를 정의한 적이 있다.

  • 변수를 정의해 놓으면 이 파일을 닫거나 혹은 일부러 메모리에서 변수를 지우기 전까지는 활성화되어 있어서 언제든지 활용할 수 있다.(단, 전역변수의 경우에만 해당한다. 이는 추후에 다룬다.)

fizz + eggs

연습문제#

😄문제 1. 다음 내용을 코드로 작성하시오.

  • 변수 insa에 ‘Hello!’를 저장하시오.

  • 변수 name에 본인 이름을 영어로 저장하시오.

  • Hello!와 본인 이름 사이에 공백을 추가해서 출력하시오. (예: Hello! Alice)

😄문제2. 변수활용하여 수식으로 표현해보기

x는 3이다. 변수 x를 활용하여 수식을 작성해보고 y를 출력하시오.

\( y=[\{(𝑥^2−2𝑥)−6\}×2]+(3𝑥−3)÷2 \)

😄문제3. 문자열 표현해보기

변수 name에 ‘지수’를 넣고 변수를 활용하여 3번 연속으로 ‘지수야 반가워’를 출력하시오.

지수야 반가워 지수야 반가워 지수야 반가워

마무리#

지금까지 우리는 정수형, 실수형, 문자열 데이터 타입과 이들 데이터 타입에서 사용할 수 있는 주요 연산자를 학습했다. 또한 연산자를 활용하여 수식을 표현하는 방법을 배웠다. 마지막으로 변수의 개념과 변수를 활용하는 연습을 해보았다.

정리하자면,

  • 데이터는 그 값의 속성에 따라 타입(형)이 존재하며 프로그래밍에서는 데이터의 타입이 매우 중요하다.

  • 데이터의 타입마다 지원하는 연산이 다르다.

  • 변수는 컴퓨터 메모리 공간에 이름을 붙인 것으로 숫자나 문자열 등의 데이터를 저장하는 공간이다.

  • 변수에 새로운 값을 저장하면 이전에 있던 값은 사라진다.

  • 문자열을 표현하기 위해서는 문자열의 앞과 뒤에 홑 따옴표(‘), 쌍 따옴표(“), 트리플 따옴표(‘’’ 또는 “””) 기호를 붙인다.