Python 환경설정

pyenv

pyenv는 프로젝트별로 파이썬 버전을 따로 관리할 수 있도록 도와주는 라이브러리입니다. 여러 프로젝트를 동시에 진행하다보면, 어떤 프로젝트에서는 2.7을, 어떤 프로젝트에서는 3.4를 사용하는 식으로 다양한 버전의 사용할 수도 있고, 각각에 설치된 라이브러리간 충돌이 일어날 수도 있습니다.

virtualenv

virtualenv는 파이썬 개발환경을 프로젝트별로 분리해서 관리할 수 있게 해주는 라이브러리입니다. 위의 pyenv와 다른점은, pyenv는 파이썬의 버전을 관리해주는 것이며, virtualenv는 파이썬 패키지 설치 환경을 따로 관리해줍니다.

pyenv-virtualenv

위의 pyenv제작자가, pyenv를 사용할 경우 쉽게 virtualenv를 사용할 수 있도록 만든 라이브러리입니다.

shell 변경

기본 shell인 bash shell을 zsh shell로 변경

$ brew install zsh zsh-completions
curl -L http://install.ohmyz.sh | sh
# 기본 shell 변경
$ chsh -s `which zsh`
# 변경 확인
$ echo $SHELL
/bin/zsh

vim 명령

i - 현재 커서 위치에 insert
I - 현재 줄 맨앞에 insert
a - 현재 커서 다음칸에 insert
A - 현재 줄 맨뒤에 insert
o - 윗줄에 insert
O - 아랫줄에 insert
shift + g : 가장 아래로
shift + a : 현재 줄에서 가장 마지막으로 insert

pyenv

# 설치
$ brew install pyenv
$ brew install pyenv-virtualenv

# 설정
# vi ~/.bash_profile에서 아래파일로 변경
$ vi ~/.zshrc
# .zshrc 파일에 pyenv 설정
# brew로 설치한 디렉토리로 지정
export PYENV_ROOT=/usr/local/var/pyenv
if which pyenv > /dev/null; then eval "$(pyenv init -)"; fi
if which pyenv-virtualenv-init > /dev/null; then eval "$(pyenv virtualenv-init -)"; fi

맥에서 에러 방지를 위해 아래 작업을 진행한다.

# 아래명려해서 폴더이동을 하게 되면 brew에서 설치한 것과 home 경로 양쪽에 있는 것
# home 경로에는 apt-get을 통해 설치한 것들이 주로 있음
$ cd .pyenv
$ brew info pyenv
$ cd ..
# 해당 폴더 이동 (or 이상없는 것을 확인한 후 삭제)
$ mv .pyenv .pyenv_backup

파이썬 shell 관련 설정

shell에서 방향키 관련 이슈 해결을 위해 유틸리티 설치

$ brew install readline xz

pyenv로 파이썬 3.4.3 설치

$ pyenv
install     Install a Python version using python-build
version     Show the current Python version and its origin

$ pyenv versions
system (set by /usr/local/var/pyenv/version)

$ pyenv install 3.4.3
$ pyenv versions
* system (set by /usr/local/var/pyenv/version)
  3.4.3

가상환경

# global로 전역 설정
$ pyenv global 3.4.3
$ pyenv versions
  system
* 3.4.3 (set by /usr/local/var/pyenv/version)

# pyenv virtualenv <version> <env name>
$ pyenv virtualenv 3.4.3 fc-python

# 디렉토리 이동
$ cd your/dir/path

# local에 가상환경 지정
$ pyenv local fc-python

iPython 설치

기본 파이썬 셸보다 다양한 기능을 사용할 수 있도록 해주는 셸을 제공해줌

# 파이썬 패키지 관리자
$ pip list
pip (9.0.1)
setuptools (12.0.5)
# ipython 설치
$ pip install ipython
$ ipython
Python 3.4.3 (default, Jan 25 2017, 11:10:47)
In [1]: import this
In [2]: 24 * 3
Out[2]: 72

In [3]: "String"
Out[3]: 'String'

Python

용어

# 리터럴 (literal) : 변하지 않는 고정된 데이터 자체의 표현
# 정수형 데이터
In [1]: 7
Out[1]: 7
# 문자열 데이터
In [2]: 'python'
Out[2]: 'python'
# 부동소수점 데이터
In [3]: 3.14
Out[3]: 3.14
# 리터럴 값에는 값을 대입할 수 없다.
In [4]: 5 = 5
  File "<ipython-input-3-fd7bab309f59>", line 1
    5 = 5
         ^
SyntaxError: can\'t assign to literal

# 표현식 (expression) : 값을 의미하는 표현 또는 값을 반환하는 표현
In [1]: 24 * 7  # 표현식
Out[1]: 168  # 정수 168의 리터럴 값

# 구문 (statement) : 값의 의미를 지니지 않으며, 어떠한 목적을 수행하는 코드
In [1]: for char in 'Hello':
   ...:     print(char)
   ...:
H
e
l
l
o

실습

# 파이썬 인터프리터를 계산기처럼 사용해서 1년이 총 몇 초인지 계산해보시오.
In [1]: 60 * 60 * 24 * 360
Out[1]: 31104000

변수

파이썬은 모든것(정수, 문자열, 함수 등)이 객체(Object)로 이루어져 있다. 객체는 데이터의 형태를 결정해주는 타입으로, 파이썬에서는 객체의 타입을 바꿀 수 없다.

프로그래머는 변수를 선언하고 사용하는 형태로 컴퓨터의 메모리에 값을 할당하고, 해당 값을 참조할 수 있다.

# a: 35이라는 정수형 객체를 참조
In [1]: a = 35
# b: 35이라는 정수형 객체를 참조
In [2]: b = a
# a: 36이라는 정수형 객체를 참조
In [3]: a = a + 1
# a가 참조하고 있는 36 정수 반환
In [4]: a
Out[4]: 36
# b가 참조하고 있는 35 정수 반환
In [5]: b
Out[5]: 35
# 변수는 단지 이름일 뿐이며, 그 자체가 어떠한 값을 갖는것이 아니다.
# var1이라는 변수는 100이란 데이터를 직접 가지는 것이 아니며, 100이라는 정수형 객체가 있고 a는 단순히 해당 객체를 참조하는 역할을 한다.
In [1]: var1 = 100

In [2]: print(var1)
100

In [3]: var2 = var1

In [4]: var3 = var1

In [5]: var4 = var1

# id 내장함수 : 메모리 상에서 가지고 있는 고유의 주소(id)를 출력
In [6]: id(var1)
Out[6]: 4464628032

In [7]: id(var2)
Out[7]: 4464628032

In [8]: id(var3)
Out[8]: 4464628032

In [9]: id(var4)
Out[9]: 4464628032

# var1이 다른 객체를 참조하도록 변경했을 때,
# var2, var3, var4가 기존에 var1을 참조하던 것이 아닌,
# var1이 참조하던 객체를 참조했다는 것을 확인할 수 있다.
In [10]: var1 = 101

In [11]: id(var1)
Out[11]: 4464628064

In [12]: id(var2)
Out[12]: 4464628032

In [13]: id(var3)
Out[13]: 4464628032

In [14]: id(var4)
Out[14]: 4464628032
In [1]: a = 100

In [2]: b = 100

In [3]: id(a)
Out[3]: 4445204800

In [4]: id(b)
Out[4]: 4445204800

# 더 빠르게 작동하기 위해
# 자주 사용하는 객체들은 파이썬에서 미리 메모리에 저장
# 즉, 선언여부와 상관없이 내부적으로 객체를 생성
In [5]: c = 89723

In [6]: d = 89723

In [7]: id(c)
Out[7]: 4468721488

In [8]: id(d)
Out[8]: 4468720624

In [9]: str1 = "hello"

In [10]: str2 = "hello"

In [11]: id(str1)
Out[11]: 4477558432

In [12]: id(str2)
Out[12]: 4477558432

변수의 타입 확인

classtype은 거의 같은 의미로 사용한다.

In [1]: print(type(100))
<class 'int'>

In [2]: print(type('hello'))
<class 'str'>

변수이름

  • 소문자
  • 대문자
  • 숫자
  • 언더스코어(_)
  • 유니코드 문자(python3.x)

이름은 숫자로 시작할 수 없으며, 언더스코어로 시작하는 변수명은 특별한 처리방법을 따르므로 일반적으로 사용하지 않는다.

In [1]: 변수 = 3

In [2]: 변수
Out[2]: 3

In [3]: var = input()
43

In [4]: var = input('숫자를 입력해주세요 : ')
숫자를 입력해주세요 : 53

In [5]: print(var)
53

실습

  1. 1일이 몇 초인지 계산 후, 해당 결과를 seconds_per_day 변수에 할당하라.
  2. 1년이 몇 초인지 계산 후, 해당 결과를 seconds_per_year 변수에 할당하라.
  3. 각 변수의 타입을 확인해본다.
  4. 문자열을 입력해주세요 :라는 안내문구를 띄워주도록 input함수를 사용해본다. 결과는 var에 할당한다.
In [1]: seconds_per_day = 60 * 60 * 24

In [2]: seconds_per_year = 60 * 60 * 24 * 365

In [3]: print(type(seconds_per_day))
<class 'int'>

In [4]: print(type(seconds_per_year))
<class 'int'>

In [5]: var = input('문자열을 입력해주세요 : ')
문자열을 입력해주세요 : hello

숫자

수학 연산자

# 더하기
In [1]: 32 + 7
Out[1]: 39
# 빼기
In [2]: 82 - 2
Out[2]: 80
# 곱하기
In [3]: 3 * 7
Out[3]: 21
# 나누기
In [4]: 7 / 2
Out[4]: 3.5
# 정수나누기
In [5]: 7 // 2
Out[5]: 3
# 나머지
In [6]: 7 % 3
Out[6]: 1
# 지수
In [7]: 2**10
Out[7]: 1024

진수 (base)

기본적으로 숫자형 데이터는 10진수로 간주되지만, 파이썬에서는 2진수, 8진수, 16진수를 표현할 수 있다.

  • 2진수(binary): 0b또는 0B로 시작
  • 8진수(octal): 0o또는 0O로 시작
  • 16진수(hex): 0x또는 0X로 시작
In [1]: 10
Out[1]: 10

In [2]: 0b10
Out[2]: 2

In [3]: 0o10
Out[3]: 8

In [4]: 0x10
Out[4]: 16

형변환

내장함수 int, float를 사용

# int > float
In [1]: a = 35

In [2]: print(type(a))
<class 'int'>

In [3]: a = float(a)

In [4]: print(a)
35.0

In [5]: print(type(a))
<class 'float'>

# float > int
In [6]: b = 3.14

In [7]: print(type(b))
<class 'float'>

In [8]: b = int(b)

In [9]: print(b)
3

In [10]: print(type(b))
<class 'int'>

실습

  1. 양수 1234를 표현해본다.
  2. 음수 100을 표현해본다.
  3. 10과 3의 덧셈, 뺄셈, 곱셈, 나눗셈, 정수나눗셈, 나머지, 지수 연산을 실행해본다.
  4. c에 60을 할당 후, 산술 연산자 결합으로 아래 목록을 표현해본다.
    • 나누기연산 결과를 표현
    • 정수나누기 연산 결과를 표현
    • 나머지 결과를 표현
  5. 부동소수점수형 변수를 정수형으로 형변환 해본다.
  6. 정수형 변수를 부동소수점형으로 형변환 해본다.
In [1]: a = 1234
In [2]: a
Out[2]: 1234

In [3]: b = -100
In [4]: b
Out[4]: -100

In [5]: 10 + 3
Out[5]: 13

In [6]: 10 - 3
Out[6]: 7

In [7]: 10 * 3
Out[7]: 30

In [8]: 10 / 3
Out[8]: 3.3333333333333335

In [9]: 10 // 3
Out[9]: 3

In [10]: 10 % 3
Out[10]: 1

In [11]: 10**3
Out[11]: 1000

In [12]: c = 60
In [13]: c /= 3
In [14]: print(c)
20.0

In [15]: print(c//2)
10.0

In [16]: print(c%3)
2.0


In [17]: pi = 3.14
In [18]: print(int(pi))
3

In [19]: lucky = 7
In [20]: print(float(lucky))
7.0

문자열

문자열 표현


In [1]: 'python'
Out[1]: 'python'

In [2]: "python"
Out[2]: 'python'

In [3]: 'python "world"'
Out[3]: 'python "world"'

In [5]: "python 'world'"
Out[5]: "python 'world'"

In [6]: '''세 개의 작은 따옴표
   ...: (또는 큰따옴표)는 여러줄에 걸친 문자열을
   ...: 나타낼때 사용합니다.'''
Out[6]: '세 개의 작은 따옴표 \n(또는 큰따옴표)는 여러줄에 걸친 문자열을\n나타낼때 사용합니다.'

In [7]: long_string = '''세 개의 작은 따옴표
   ...: (또는 큰따옴표)는 여러줄에 걸친 문자열을
   ...: 나타낼때 사용합니다.'''

In [8]: print(long_string)
세 개의 작은 따옴표
(또는 큰따옴표)는 여러줄에 걸친 문자열을
나타낼때 사용합니다.

이스케이프 문자

In [1]: s = 'Python's own help system'
  File "<ipython-input-1-53f85b8f109a>", line 1
    s = 'Python's own help system'
                ^
SyntaxError: invalid syntax

# 작은따옴표 입력
In [2]: s = 'Python\'s own help system'

In [3]: print(s)
Python's own help system

# 줄바꿈 입력
In [4]: s = 'Python\'s own\n help system'

In [5]: print(s)
Python's own
 help system

# 역슬래시 입력
In [6]: s = 'Python\'s own help \\ system'

In [7]: print(s)
Python's own help \ system

문자열 더하기

In [1]: notice = ''

In [2]: print(notice)


In [3]: notice += '공지사항'

In [4]: print(notice)
공지사항

In [5]: notice += ' (패치노트)'

In [6]: print(notice)
공지사항 (패치노트)

형번환

내장함수 str 사용

In [1]: number = 147

In [2]: print(type(number))
<class 'int'>

In [3]: number = str(number)

In [4]: print(type(number))
<class 'str'>

In [5]: print(number)
147

인덱스 연산

문자열은 기본적으로 시퀀스 타입이다. 가장 왼쪽은 0이며, 가장 오른쪽은 -1로 시작한다.

In [1]: lux = '빛으로 강타해요!'

In [2]: lux[0]
Out[2]: '빛'

In [3]: lux[-1]
Out[3]: '!'

# 범위를 넘을 때
In [4]: lux[50]
------------------------------------------------------
IndexError: string index out of range

# 문자열은 불변이므로 새 값을 대입할 수 없다.
In [5]: lux[0] = '손'
------------------------------------------------------
TypeError: 'str' object does not support item assignment

슬라이스 연산

In [1]: long_string = 'Introduction and overview of IPython features.'

# [start:] start 부터 마지막까지
In [2]: long_string[10:]
Out[2]: "on and overview of IPython features."

# [:end] 처음부터 end 까지
In [3]: long_string[:5]
Out[3]: 'Intro'

# [start:end] start부터 end 까지
In [4]: long_string[7:15]
Out[4]: 'ction an'

# [start:end:step] start부터 end 까지 sept 만큼씩 뛰어넘은 부분
In [5]: long_string[13:20:3]
Out[5]: 'a e'

길이

내장함수 len사용한다. 영어, 한글 상관없이 한글자로 처리한다.

In [1]: korean_string = '이것은 긴 문자열입니다'

In [2]: len(korean_string)
Out[2]: 12

In [3]: english_string = 'This is string'

In [4]: len(english_string)
Out[4]: 14

문자열 나누기(split)

문자열 내장함수 split을 사용한다. split함수에 인자로 주어진 구분자를 기준으로 문자열을 리스트 형태로 반환한다.

In [1]: girlsday = '민아,유라,소진,혜리'

In [2]: girlsday.split(',')
Out[2]: ['민아', '유라', '소진', '혜리']

In [3]: girlsday = '민아 유라 소진 혜리'

# split 함수에 인자를 주지 않을 경우, 공백문자를 구분자로 사용
# 인자를 주지 않은 경우와 ' '를 준 경우 결과가 같다.
In [4]: girlsday.split(' ')
Out[4]: ['민아', '유라', '소진', '혜리']

In [5]: girlsday.split()
Out[5]: ['민아', '유라', '소진', '혜리']

문자열 결합(join)

split 함수와 반대의 역할을 한다. 문자열 리스트를 하나의 문자열로 결합한다.

In [6]: girlsday_list = girlsday.split()

In [7]: print(girlsday_list)
['민아', '유라', '소진', '혜리']

In [8]: ', '.join(girlsday_list)
Out[8]: '민아, 유라, 소진, 혜리'

대소문자 다루기

In [1]: lux = 'lux, the LADY of Luminosity'

In [2]: lux.capitalize()
Out[2]: 'Lux, the lady of luminosity'

In [3]: lux.title()
Out[3]: 'Lux, The Lady Of Luminosity'

In [4]: lux.upper()
Out[4]: 'LUX, THE LADY OF LUMINOSITY'

In [5]: lux.lower()
Out[5]: 'lux, the lady of luminosity'

In [6]: lux.swapcase()
Out[6]: 'LUX, THE lady OF lUMINOSITY'

문자열 포맷

옛 스타일(%)
In [1]: '%s' % 42
Out[1]: '42'

In [2]: '%d x %d : %d' % (3, 4, 12)
Out[2]: '3 x 4 : 12'

# 리터럴 %는 %%로 표시e
In [3]: '%d % %d : %d' % (12, 4, 0)
------------------------------------------------------
TypeError: not all arguments converted during string formatting

In [4]: '%d %% %d : %d' % (12, 4, 0)
Out[4]: '12 % 4 : 0'
정렬
In [1]: d = 37
In [2]: f = 3.14
In [3]: s = 'Python'

In [4]: '%d %f %s' % (d, f, s)
Out[4]: '37 3.140000 Python'

# 전체글자수 10 지정
In [5]: '%10d %10d %10s' % (d, f, s)
Out[5]: '        37          3     Python'

# 왼쪽정렬 -
In [6]: '%-10d %-10d %-10s' % (d, f, s)
Out[6]: '37         3          Python    '

# 문자길이 3 지정
In [7]: '%-10.3d %-10.3d %-10.3s' % (d, f, s)
Out[7]: '037        003        Pyt       '
새 스타일 ({}, format)
In [1]: d = 37
In [2]: f = 3.14
In [3]: s = 'Python'

# 기본 형태
In [4]: '{} {} {}'.format(d, f, s)
Out[4]: '37 3.14 Python'

# 각 인자의 순서를 지정
In [5]: '{1} {2} {0}'.format(d, f, s)
Out[5]: '3.14 Python 37'

# 각 인자에 이름을 지정
In [6]: '{d} {f} {s}'.format(d=50, f=1.432, s='WPS')
Out[6]: '50 1.432 WPS'

# 딕셔너리로부터 변수 할당
# {0[d]}에서 0은 인자의 순서
In [7]: dic = {'d': d, 'f': f, 's': s}
In [8]: '{0[d]} {0[f]} {0[s]} {1}'.format(dic, 'WPS')
Out[8]: '37 3.14 Python WPS'

# 타입지정자 입력
In [9]: '{:d} {:f} {:s}'.format(d, f, s)
Out[9]: '37 3.140000 Python'

# 이름과 타입지정자 모두 사용
In [12]: '{digit:d} {float:f} {string:s}'.format(digit=700, float=1.43, string='Welcome')
Out[12]: '700 1.430000 Welcome'

# 이름을 지정한 인자는 맨 뒤에 입력
In [20]: '{data:d} {:f} {:s}'.format(data=d, f, s)
  File "<ipython-input-20-cabe6f92c605>", line 1
    '{data:d} {:f} {:s}'.format(data=d, f, s)
                                       ^
SyntaxError: non-keyword arg after keyword arg


In [21]: '{data:d} {:f} {:s}'.format(f, s, data=d)
Out[21]: '37 3.140000 Python'

# 필드 길이 10, 우측정렬
In [13]: '{:10d}'.format(d)
Out[13]: '        37'

In [14]: '{:>10d}'.format(d)
Out[14]: '        37'

# 필드길이 10, 좌측정렬
In [15]: '{:<10d}'.format(d)
Out[15]: '37        '

# 필드길이 10, 가운데 정렬
In [16]: '{:^10d}'.format(d)
Out[16]: '    37    '

# 필드길이 10, 가운데 정렬, 빈공간은 ~로 채움
In [17]: '{:~^10d}'.format(d)
Out[17]: '~~~~37~~~~'

실습

  1. 여러 줄의 텍스트를 multi_lines변수에 할당하고, print()함수로의 출력과 인터프리터의 자동 출력(변수명 입력)을 비교해보시오.
  2. str1, str2변수에 각각 문자열을 할당하고, 두 변수를 결합해 str3변수에 할당해보시오.
  3. str1변수에 *연산자를 사용한 결과를 출력해보시오.
In [1]: multi_lines = '''여러줄의 텍스트를 입력합니다.
   ...: print() 함수의 출력과
   ...: 인터프리터 출력을 비교합니다.'''

In [2]: print(multi_lines)
여러줄의 텍스트를 입력합니다.
print() 함수의 출력과
인터프리터 출력을 비교합니다.

In [3]: multi_lines
Out[3]: '여러줄의 텍스트를 입력합니다.\nprint() 함수의 출력과 \n인터프리터 출력을 비교합니다.'


In [4]: str1 = "hello"

In [5]: str2 = "python"

In [6]: str3 = str1 + str2

In [7]: print(str3)
hellopython


In [8]: str1 * 3
Out[8]: 'hellohellohello'

시퀀스타입

파이썬에 내장된 시퀀스 타입에는 문자열, 리스트, 튜플이 있다. 문자열은 인용부호(작은따옴표, 큰따옴표)를 사용하며, 리스트는 대괄호[], 튜플은 괄호()를 사용하여 나타낸다. 시퀀스 타입의 객체는 인덱스 연산을 통해 내부 항목에 접근 할 수 있다.

리스트

리스트는 순차적인 데이터를 나타내는 데 유용하며, 문자열과는 달리 내부 항목을 변경할 수 있다.

# 리스트 생성
In [1]: empty_list1 = []
In [2]: empty_list2 = list()
In [3]: sample_list = ['a', 'b', 'c', 'd']
In [4]: sample_list2 = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']

# 다른 데이터를 리스트로 변환 (리스트로 변환 가능한 타입에서 사용가능)
# 반환된 리스트 값을 변수에 저장하지 않으면 사라진다.
In [1]: print(list('League of legends'))
['L', 'e', 'a', 'g', 'u', 'e', ' ', 'o', 'f', ' ', 'l', 'e', 'g', 'e', 'n', 'd', 's']

In [2]: lol = list('League of legends')
In [3]: print(lol)
['L', 'e', 'a', 'g', 'u', 'e', ' ', 'o', 'f', ' ', 'l', 'e', 'g', 'e', 'n', 'd', 's']


# 인덱스 연산
# sample_list2를 이용해 5월, 7월을 추출
In [7]: sample_list2[4]
Out[7]: 'May'

In [8]: sample_list2[6]
Out[8]: 'Jul'

# 내부항목 변경
# sample_list를 이용해 3번째 요소인 'c'를 대문자 'C'로 변환
In [9]: sample_list[2] = 'C'

In [10]: print(sample_list)
['a', 'b', 'C', 'd']

# 슬라이스 연산
# sample_list2를 이용, 1월부터 3월씩 건너뛴 결과를 quarters에 할당
In [11]: quaters = sample_list2[::3]
In [12]: print(quaters)
['Jan', 'Apr', 'Jul', 'Oct']
# sample_list2를 이용, 끝에서부터 3번째 요소까지를 last_three에 할당
In [18]: last_three = sample_list2[-3:]
In [19]: print(last_three)
['Oct', 'Nov', 'Dec']
# sample_list2를 이용, 끝에서부터 처음까지(거꾸로) 2월씩 건너뛴 결과를 reverse_two_steps에 할당
In [20]: reverse_tow_steps = sample_list2[::-2]
In [21]: print(reverse_tow_steps)
['Dec', 'Oct', 'Aug', 'Jun', 'Apr', 'Feb']
리스트 항목 추가 (append)
# 리스트 항목 추가
# append
In [23]: sample_list.append('e')

In [24]: sample_list
Out[24]: ['a', 'b', 'C', 'd', 'e']

특정 위치에 리스트 항목 추가 (insert)
In [1]: fruits = ['apple', 'banana', 'melon']

In [3]: fruits.insert(1, 'mango')

In [4]: fruits
Out[4]: ['apple', 'mango', 'banana', 'melon']

# 인덱스 범위를 넘어가면 맨 끝에 추가
In [5]: fruits.insert(100, 'pineapple')

In [6]: fruits
Out[6]: ['apple', 'mango', 'banana', 'melon', 'pineapple']
리스트 병합 (extend, +=)
In [1]: fruits = ['apple', 'banana', 'melon']
In [2]: colors = ['red', 'green', 'blue']
# extend
In [3]: fruits.extend(colors)

In [4]: fruits
Out[4]: ['apple', 'banana', 'melon', 'red', 'green', 'blue']

# +=
In [5]: fruits += colors

In [6]: fruits
Out[6]: ['apple', 'banana', 'melon', 'red', 'green', 'blue', 'red', 'green', 'blue']
리스트 복사
  • copy 함수
  • list 함수
  • 슬라이스 연산 [:]
# 리스트를 복사하는 3가지 방법이 있으나,
# copy 함수를 사용하는 것이 좋다.
In [1]: fruits = ['apple', 'banana', 'melon']
In [3]: colors = ['red', 'geen', 'blue']

In [11]: id(fruits)
Out[11]: 4531118664
# copy 함수
In [12]: fruits_ori = fruits.copy()

In [13]: id(fruits_ori)
Out[13]: 4531079752

In [14]: fruits.append(colors)

In [15]: fruits
Out[15]: ['apple', 'banana', 'melon', ['red', 'geen', 'blue']]

In [16]: id(fruits)
Out[16]: 4531118664

# 메모리의 다른 공간에 객체를 생성하고 그 주소를 참조
# 리스트는 주소 뿐만 아니라 값도 가지고 있다.
In [17]: fruits = fruits_ori

In [18]: fruits
Out[18]: ['apple', 'banana', 'melon']

In [19]: id(fruits)
Out[19]: 4531079752

In [20]: fruits_link = fruits
# copy 함수
In [21]: fruits_copy = fruits.copy()
# list 함수
In [22]: fruits_list = list(fruits)

In [23]: id(fruits)
Out[23]: 4531079752

In [24]: id(fruits_link)
Out[24]: 4531079752

In [25]: id(fruits_copy)
Out[25]: 4531110664

In [26]: id(fruits_list)
Out[26]: 4530521608
# 슬라이스 연산
In [27]: fruits_slice = fruits[:]

In [28]: id(fruits_slice)
Out[28]: 4531066312
특정 위치 리스트 항목 삭제 (del)

del은 리스트 함수가 아닌, 파이썬 구문이므로 del <list>[offset] 형식을 사용한다.

In [38]: fruits += colors

In [39]: fruits
Out[39]: ['apple', 'banana', 'melon', 'red', 'geen', 'blue']

In [40]: del fruits[0]

In [49]: del fruits[30]
------------------------------------------------------
IndexError: list assignment index out of range
값으로 리스트 항목 삭제 (remove)
In [42]: fruits.remove('banana')

In [43]: fruits
Out[43]: ['melon', 'red', 'geen', 'blue']

In [50]: fruits.remove('test')
------------------------------------------------------
ValueError: list.remove(x): x not in list
리스트 항목 추출 후 삭제 (pop)
In [44]: fruits.pop()
Out[44]: 'blue'

In [45]: fruits
Out[45]: ['melon', 'red', 'geen']

In [46]: fruits.pop(-3)
Out[46]: 'melon'

In [47]: fruits
Out[47]: ['red', 'geen']
값으로 리스트 항목 오프셋 찾기 (index)
In [51]: fruits.index('red')
Out[51]: 0
존재여부 확인 (in)
In [52]: 'red' in fruits
Out[52]: True
값 세기 (count)
In [53]: fruits.append('red')
In [55]: fruits.append('red')
In [56]: fruits.count('red')
Out[56]: 3
정렬하기 (sort, sorted)
  • sort는 리스트 자체를 정렬 (원본을 바꿈)
  • sorted는 리스트의 정렬 복사본을 반환
In [57]: colors
Out[57]: ['red', 'geen', 'blue']

In [58]: colors.sort()

In [59]: colors
Out[59]: ['blue', 'geen', 'red']

In [60]: sample_list = ['a', 'b', 'c', '가', '나', '다']

In [61]: ordered_list = sorted(sample_list)

# 유니코드 정의 순서대로 정렬
In [62]: ordered_list
Out[62]: ['a', 'b', 'c', '가', '나', '다']

In [63]: sample_list
Out[63]: ['a', 'b', 'c', '가', '나', '다']

튜플

튜플은 리스트와 비슷하나, 정의 후 내부 항목의 삭제나 수정이 불가능하다.

In [1]: empty_tuple = ()
# 튜플을 정의할 때는 괄호가 없어도 무관하나,
# 괄호로 묶는것이 좀 더 튜플임을 구분하기 좋다.
# 또한, 튜플의 요소가 1개일 때는 요소의 뒤에 쉼표(,)를 붙여야 한다.
In [2]: color = 'green'
In [3]: colors = 'red',
In [4]: fruits = 'apple', 'banana'

In [5]: colors
Out[5]: ('red',)

In [6]: fruits
Out[6]: ('apple', 'banana')

In [7]: print(type(color))
<class 'str'>

In [8]: print(type(colors))
<class 'tuple'>

튜플 언패킹
In [9]: f1, f2 = fruits

In [10]: f1
Out[10]: 'apple'

In [11]: f2
Out[11]: 'banana'
형 변환

tuple 함수 사용 (튜플 생성에는 사용 불가능), 리스트를 튜플로 변환

튜플을 사용하는 이유

  • 리스트보다 적은 메모리 사용
  • 정의 후에는 변하지 않는 내부 값
In [1]: fruit = ['apple', 'banana', 'orange']

In [2]: t = tuple(fruit)

In [3]: t
Out[3]: ('apple', 'banana', 'orange')

In [4]: ', '.join(t)
Out[4]: 'apple, banana, orange'

In [5]: ','.join(t)
Out[5]: 'apple,banana,orange'

In [6]: ','.join(t).split(',')
Out[6]: ['apple', 'banana', 'orange']
실습
  1. 문자열 ‘Python’을 리스트, 튜플 타입으로 형변환하여 새 변수에 할당한다.
  2. 1번에서 할당한 리스트, 튜플 변수를 이용해 다시 문자열을 만든다.
In [1]: sample_string = 'Python'

In [2]: sample_string_list = list(sample_string)

In [3]: sample_string_list
Out[3]: ['P', 'y', 't', 'h', 'o', 'n']

In [4]: sample_string_tuple = tuple(sample_string_list)

In [5]: sample_string_tuple
Out[5]: ('P', 'y', 't', 'h', 'o', 'n')


In [6]: ', '.join(sample_string_list)
Out[6]: 'P, y, t, h, o, n'

In [7]: ''.join(sample_string_list)
Out[7]: 'Python'

In [8]: ', '.join(sample_string_tuple)
Out[8]: 'P, y, t, h, o, n'

In [9]: ''.join(sample_string_tuple)
Out[9]: 'Python'

딕셔너리, 셋

딕셔너리 (dictionary)

Key-Value형태로 항목을 가지는 자료구조.

생성
In [1]: empty_dict1 = {}

In [2]: empty_dict2 = dict()

In [3]: champion_dict = {
   ...: 'Lux': 'the Lady of Luminosity',
   ...: 'Ahri': 'the Nine-Tailed Fox',
   ...: 'Ezreal': 'the Prodigal Explorer',
   ...: 'Teemo': 'the Swift Scout',
   ...: }
형변환

dict 함수를 사용, 두 값의 시퀀스(리스트 또는 튜플)을 딕셔너리로 변환한다.

In [4]: sample = [[1,2], [3,4], [5,6]]

In [5]: dict(sample)
Out[5]: {1: 2, 3: 4, 5: 6}
항목 찾기/추가/변경 [key]
In [3]: champion_dict = {
   ...: 'Lux': 'the Lady of Luminosity',
   ...: 'Ahri': 'the Nine-Tailed Fox',
   ...: 'Ezreal': 'the Prodigal Explorer',
   ...: 'Teemo': 'the Swift Scout',
   ...: }

# 찾기
In [6]: champion_dict['Lux']
Out[6]: 'the Lady of Luminosity'
# 추가
In [7]: champion_dict['Sona'] = 'Maven of the String'
# 변경
In [8]: champion_dict['Lux'] = 'Demacia'

In [9]: champion_dict
Out[9]:
{'Ahri': 'the Nine-Tailed Fox',
 'Ezreal': 'the Prodigal Explorer',
 'Lux': 'Demacia',
 'Sona': 'Maven of the String',
 'Teemo': 'the Swift Scout'}
결합 (update)
In [10]: item_dict = {
    ...: 'Doran Ring': 400,
    ...: 'Doran Blade': 450,
    ...: 'Doran Shield' : 450,
    ...: }

In [11]: com_dict = {}

In [12]: com_dict.update(champion_dict)

In [13]: com_dict
Out[13]:
{'Ahri': 'the Nine-Tailed Fox',
 'Ezreal': 'the Prodigal Explorer',
 'Lux': 'Demacia',
 'Sona': 'Maven of the String',
 'Teemo': 'the Swift Scout'}

In [14]: com_dict.update(item_dict)

In [15]: com_dict
Out[15]:
{'Ahri': 'the Nine-Tailed Fox',
 "Doran Blade": 450,
 "Doran Ring": 400,
 "Doran Shield": 450,
 'Ezreal': 'the Prodigal Explorer',
 'Lux': 'Demacia',
 'Sona': 'Maven of the String',
 'Teemo': 'the Swift Scout'}

# 같은 키가 있을 경우
# update에 주어진 딕셔너리 값이 할당
In [16]: com_dict.update({'Lux': 'Test'})

In [17]: com_dict
Out[17]:
{'Ahri': 'the Nine-Tailed Fox',
 "Doran Blade": 450,
 "Doran Ring": 400,
 "Doran Shield": 450,
 'Ezreal': 'the Prodigal Explorer',
 'Lux': 'Test',
 'Sona': 'Maven of the String',
 'Teemo': 'the Swift Scout'}
삭제 (del)
In [22]: com_dict
Out[22]:
{'Ahri': 'the Nine-Tailed Fox',
 "Doran Blade": 450,
 "Doran Ring": 400,
 "Doran Shield": 450,
 'Ezreal': 'the Prodigal Explorer',
 'Lux': 'Test',
 'Sona': 'Maven of the String',
 'Teemo': 'the Swift Scout'}

In [23]: del com_dict['Doran Blade']

In [24]: del com_dict['Doran Ring']

In [25]: com_dict
Out[25]:
{'Ahri': 'the Nine-Tailed Fox',
 "Doran Shield": 450,
 'Ezreal': 'the Prodigal Explorer',
 'Lux': 'Test',
 'Sona': 'Maven of the String',
 'Teemo': 'the Swift Scout'}
전체 삭제 (clear)

전체 항목을 삭제

In [26]: com_dict.clear()

In [27]: com_dict
Out[27]: {}
in으로 키 검색

True/False 반환

In [28]: champion_dict
Out[28]:
{'Ahri': 'the Nine-Tailed Fox',
 'Ezreal': 'the Prodigal Explorer',
 'Lux': 'Demacia',
 'Sona': 'Maven of the String',
 'Teemo': 'the Swift Scout'}

In [29]: 'Lux' in champion_dict
Out[29]: True

In [30]: 'Zed' in champion_dict
Out[30]: False
키 또는 값 얻기
# keys()
# 모든 키 얻기
In [31]: champion_dict.keys()
Out[31]: dict_keys(['Ahri', 'Sona', 'Teemo', 'Lux', 'Ezreal'])

# values()
# 모든 값 얻기
In [32]: champion_dict.values()
Out[32]: dict_values(['the Nine-Tailed Fox', 'Maven of the String', 'the Swift Scout', 'Demacia', 'the Prodigal Explorer'])

# items()
# 모든 키-값 얻기 (튜플로 반환)
In [33]: champion_dict.items()
Out[33]: dict_items([('Ahri', 'the Nine-Tailed Fox'), ('Sona', 'Maven of the String'), ('Teemo', 'the Swift Scout'), ('Lux', 'Demacia'), ('Ezreal', 'the Prodigal Explorer')])
복사 (copy)
In [34]: champion_dict
Out[34]:
{'Ahri': 'the Nine-Tailed Fox',
 'Ezreal': 'the Prodigal Explorer',
 'Lux': 'Demacia',
 'Sona': 'Maven of the String',
 'Teemo': 'the Swift Scout'}

In [35]: champion_dict_backup = champion_dict.copy()

In [36]: champion_dict_backup
Out[36]:
{'Ahri': 'the Nine-Tailed Fox',
 'Ezreal': 'the Prodigal Explorer',
 'Lux': 'Demacia',
 'Sona': 'Maven of the String',
 'Teemo': 'the Swift Scout'}

셋 (set)

셋은 키만 있는 딕셔너리와 같으며, 중복된 값이 존재할 수 없다.

생성
In [1]: empty_set = set()

In [2]: champions = {'lux', 'ahri', 'ezreal'}
형변환

문자열, 리스트, 튜플, 딕셔너리를 set으로 변환할 수 있으며, 중복 값이 사라진다.

리스트 중복 값을 제거할 때, 형번환을 해주면된다.

# 문자열
In [3]: lol = 'league of legend'

In [4]: lol_set = set(lol)

In [5]: lol_set
Out[5]: {' ', 'a', 'd', 'e', 'f', 'g', 'l', 'n', 'o', 'u'}

# 딕셔너리
# 딕셔너리는 키만 남는다.
In [6]: champion_dict = {
   ...: 'Lux': 'the Lady of Luminosity',
   ...: 'Ahri': 'the Nine-Tailed Fox',
   ...: 'Ezreal': 'the Prodigal Explorer',
   ...: 'Teemo': 'the Swift Scout',
   ...: }

In [7]: set(champion_dict)
Out[7]: {'Ahri', 'Ezreal', 'Lux', 'Teemo'}

In [8]: champion_dict = {
   ...: 'Lux': 'the Lady of Luminosity',
   ...: 'Ahri': 'the Nine-Tailed Fox',
   ...: 'Ezreal': 'the Prodigal Explorer',
   ...: 'Teemo': 'the Swift Scout',
   ...: 'Lux' : 'test',
   ...: }

In [9]: set(champion_dict)
Out[9]: {'Ahri', 'Ezreal', 'Lux', 'Teemo'}

# 리스트
In [10]: colors = ['red', 'blue', 'orange']

In [11]: set(colors)
Out[11]: {'blue', 'orange', 'red'}

In [12]: colors = ['red', 'blue', 'orange', 'red']

In [13]: set(colors)
Out[13]: {'blue', 'orange', 'red'}
집합 연산
In [1]: a = {1, 2, 3, 4, 5}

In [2]: b = {4, 5, 6, 7, 8, 9}

In [3]: c = {4, 5, 6}

# | : 합집합(Union)
# 집합의 모든 원소를 합쳐 놓은 집합
In [4]: a|b
Out[4]: {1, 2, 3, 4, 5, 6, 7, 8, 9}

# & : 교집합(Intersection)
# 두 집합의 공통적으로 포함하는 원소로 이루어진 집합
In [6]: a&b
Out[6]: {4, 5}

# - : 차집합(Difference)
# b에 대한 a의 차집합은, b의 원소 중 a원소가 아닌 것들의 집합
In [7]: a-b
Out[7]: {1, 2, 3}

# ^ : 대칭차집합(Exclusive)
# 둘 중 한집에는 속하지만 둘 모두에는 속하지 않는 원소들의 집합
In [8]: a^b
Out[8]: {1, 2, 3, 6, 7, 8, 9}

# <= : 부분집합(Subset)
In [10]: a <= b
Out[10]: False

In [11]: c <= b
Out[11]: True

# < : 진부분집합(Proper subset)
# 부분집합 중 자기 자신을 제외한 집합
In [12]: c < b
Out[12]: True

In [13]: d = b

In [14]: d
Out[14]: {4, 5, 6, 7, 8, 9}

In [15]: d < b
Out[15]: False

# >= : 상위집합(Superset)
# 어떤 집합이 다른 집합을 포함하고 있는지
In [16]: b <= b
Out[16]: True

In [22]: c <= b
Out[22]: True

# > : 진상위집합(Proper superset)
In [17]: b < b
Out[17]: False

In [20]: c < b
Out[20]: True

실습

  1. 6가지 색상의 영어 키, 한글 값을 갖는 딕셔너리(colors)를 생성한다. (red, green, blue, yellow, black, white)
  2. colors에서 blue키의 값을 출력한다.
  3. colors를 셋(Set)으로 만들어 colors_set변수에 할당한다.
  4. colors_set에 purple이 존재하는지 확인한다.
  5. [2,4,3,7,6,8,4,6,5,3,2,5,6,7,3]에서 중복된 값을 없애고, 오름차순으로 정렬한 list를 반환한다.
  6. 2차원 딕셔너리인 lol을 만든다.
    • lol딕셔너리의 champions키에 셋(Set)을 이용해 lux, ahri, ezreal을 할당하고,
    • lol딕셔너리의 items키에 아래의 각 항목들을 딕셔너리를 이용해 리스트로 할당한다.
    • Key: Doran Ring, Value: 400
    • Key: Doran Blade, Value: 450
  7. x = {1,2,3,4,5,6,8}, y={4,5,6,9,10,11}, z={4,6,8,9,7,10,12}일 때,
    • x,y,z의 교집합에 해당하는 숫자는?
    • y,z의 교집합이며 x에는 속하지 않는 숫자는?
    • x에만 속하고 y,z에는 속하지 않는 숫자는?
In [1]: colors = {
   ...:     'red': '빨강',
   ...:     'green': '초록',
   ...:     'blue': '파랑',
   ...:     'yellow': '노랑',
   ...:     'black': '검정',
   ...:     'white': '하얀',
   ...: }

In [2]: colors
Out[2]:
{'black': '검정',
 'blue': '파랑',
 'green': '초록',
 'red': '빨강',
 'white': '하얀',
 'yellow': '노랑'}


In [3]: colors['blue']
Out[3]: '파랑'


In [4]: colors_set = set(colors)


In [5]: 'purple' in colors_set
Out[5]: False


In [21]: numbers = [2,4,3,7,6,8,4,6,5,3,2,5,6,7,3]

In [22]: numbers_list = list(set(numbers))

In [24]: numbers_list
Out[24]: [2, 3, 4, 5, 6, 7, 8]

In [25]: numbers_list.sort()


In [29]: lol = {
    ...:     'champions': {'lux', 'ahri', 'ezreal'},
    ...:     'items': [
    ...:         {'Doran Ring': 400},
    ...:         {'Doran Blade': 450},
    ...:         ]
    ...: }

In [30]: lol
Out[30]:
{'champions': {'ahri', 'ezreal', 'lux'},
 'items': [{'Doran Ring': 400}, {'Doran Blade': 450}]}


In [33]: x = {1,2,3,4,5,6,8}

In [34]: y = {4,5,6,9,10,11}

In [35]: z = {4,6,8,9,7,10,12}

In [36]: x & y & z
Out[36]: {4, 6}

In [37]: (y & z) - x
Out[37]: {9, 10}

In [39]: x - (y|z)
Out[39]: {1, 2, 3}

QnA

문자열에 replace를 쓰면 수정이되는데 문자열이 불변하다는 것의 의미는?

실제 메모리에 저장되어 있는 문자열 값은 변하지않는다. replace를 이용해 바뀐 문자열 값을 저장하고 있는 새로운 문자열을 만들어 그 값을 반환한다.

In [1]: abc = 'lux'

In [2]: id(abc)
Out[2]: 4348767176

In [3]: abc = 'ahri'

In [4]: id(abc)
Out[4]: 4348832824

# 리스트는 주소 뿐만 아니라 값도 가지고 있다.
In [5]: list_var = ['lux']

In [6]: id(list_var)
Out[6]: 4358035528

In [7]: list_var[0] = 'ahri'

In [8]: id(list_var)
Out[8]: 4358035528

In [9]: champion = 'lux'

In [10]: champion.replace('l', 'a')
Out[10]: 'aux'

In [11]: champion
Out[11]: 'lux'
extend와 append 의 차이

In [1]: list1 = []

In [2]: list2 = ['a', 'b']

In [3]: list3 = ['c', 'd']

In [4]: list1.append(list2)

In [5]: list1.append(list3)

In [6]: list1
Out[6]: [['a', 'b'], ['c', 'd']]

In [7]: len(list1)
Out[7]: 2

In [8]: list4 = []

In [9]: list4.extend(list2)

In [10]: list4.extend(list3)

In [11]: list4
Out[11]: ['a', 'b', 'c', 'd']

In [12]: len(list4)
Out[12]: 4