- 오늘오전: 자료형, 오브젝트 ..

- 오늘오후: 참조, 얕은복사, 깊은복사

- 내일오전: 뷰와 카피

- 내일오후: 개발환경 비교

a=[1,2,3]
a
[1, 2, 3]
b=a
b
[1, 2, 3]
a.append(4) 
a
[1, 2, 3, 4]
b
[1, 2, 3, 4]

0차원 자료형의 소개

- 0차원 자료형: 하나의 값을 저장할 수 있는 자료형

- int, bool, float

a=100
type(a)
int
a=1.2*3 
a
3.5999999999999996
type(a)
float
a=True 
b=False 
type(a)
bool

- 0차원 자료형이 int, bool, float 3개만 있는 것은 아니다.

a=1+1j
b=2-2j
type(a)
complex
c=a+b
c
(3-1j)
type(c)
complex
  • 잘 쓰지 않음

0차원 자료형의 변환

- float $\to$ int

a=3.14122222
a
3.14122222
b=int(a)
b
3

- int $\to$ float

a=3 
type(a)
int
b=float(a)
type(b)
float

- bool $\to$ int, bool $\to$ float (이게 가능하지 않을것 같지만 사실 가능함)

a=True
int(a)
1
float(a)
1.0
b=False
int(b)
0
float(b)
0.0

- "이런건 변환 못하겠지?" 싶은것도 바꿔줌

bool(-3.14)
True
  • 저는 이런걸 쓰지 않아요..

- 형변환이 항상 성공하는것은 아님 (규칙은 잘 모르겠음)

float(3+0j)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-48-804a051fe87a> in <module>
----> 1 float(3+0j)

TypeError: can't convert complex to float

- 묵시적 형변환 (약간 눈치주는 느낌)

  • explicit: 온풍기를 좀 키자..
  • implicit: 날이 좀 춥지 않어..? (온풍기좀 틀자는 이야기)
True*1 
1
  • 1을 곱해야하는데..? 너 계속 bool형태로 있을거야??
1*1.0 
1.0
  • 1.0을 곱할건데..? 너 계속 int형으로 있을거야??

1차원 자료형의 소개

- 기본적인 1차원 자료형은 리스트와 튜플이 있다.

a=[1,2,3] ## 리스트 
a
[1, 2, 3]
type(a)
list
b=(1,2,3) ## 튜플 
b
(1, 2, 3)
type(b)
tuple

- 리스트와 튜플 모두 원소에 접근하기 위해서 []를 사용한다. (R과 동일)

a[0]
1
a[1]
2
a[2]
3
b[0]
1
b[1]
2
b[2]
3

- 리스트는 원소의 값을 바꿀 수 있지만 튜플은 바꿀 수 없다.

a
[1, 2, 3]
a[0]=100
a
[100, 2, 3]
b
(1, 2, 3)
b[0]=100
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-67-2a3fb166f233> in <module>
----> 1 b[0]=100

TypeError: 'tuple' object does not support item assignment

- 문자열도 1차원자료형으로 생각한다. (조금 의외임)

a='guebin' 
type(a)
str
a[0]
'g'
a[1]
'u'

- 그밖에 집합, 딕셔너리와 같은 1차원 자료형도 있다. (여기서는 자세히 다루지 않음)

s={1,2,3,4,4}
s
{1, 2, 3, 4}
type(s)
set
d={'a':123,'b':234 ,'c':233}
d
{'a': 123, 'b': 234, 'c': 233}
type(d)
dict
d['a']
123
d[0]
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-93-123a9cc6df61> in <module>
----> 1 d[0]

KeyError: 0

- 원소에 접근할 수 있는 자료형인지 없는 자료형인지 파악하는 방법?

  • dir()을 사용했을 경우 __getitem__ 이 보이면 원소에 접근할 수 있는 자료형임.
a=[1,2,3]
a.__getitem__?
Docstring: x.__getitem__(y) <==> x[y]
Type:      builtin_function_or_method
a.__getitem__(1) ## a[1]
2

리스트공부 1단계

- 리스트의 선언

a=[1,2,3]
a
[1, 2, 3]
type(a)
list

- 비어있는 리스트를 선언

a=list() ## 방법1
a
[]
a=[] ## 방법2
a
[]

- 리스트에서 +의 의미

a=[1,2,3]
b=[4,5,6] 
a+b 
[1, 2, 3, 4, 5, 6]
  • 충격.. 리스트에서는 + 연산자를 쓰면 우리가 상식적으로 생각하는 벡터연산이 수행되지 않음.

- 리스트에서 *의 의미

a=[1,2,3]
a+a
[1, 2, 3, 1, 2, 3]
a*2 ## a+a?? 
[1, 2, 3, 1, 2, 3]
[1]*10 
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

- 예제: 비어있는 리스트를 만들고 [1], [2], [3]을 각각 더하여 원소를 추가해보자.

a=[]
a
[]
a=a+[1] 
a
[1]
a=a+[2]
a
[1, 2]
a=a+[3]
a
[1, 2, 3]

리스트공부 2단계

- 리스트에서 원소를 추가하는 또 다른 방법

a = [] 
a += [1] 
a += [2] 
a += [3] 
a
[1, 2, 3]

- 리스트에서 원소를 추가하는 또 또 다른 방법

a=[]
a
[]
a.append(1)
a
[1]
a.append(2)
a
[1, 2]
a.append(3)
a
[1, 2, 3]

- a.append(1)이라는 문법이 너무 낯설어요 $\to$ 당연해요

  • 파이썬 특징: 모든 변수명 뒤에 .을 붙이면 그 변수에 특화된 새로운 기능을 쓸 수 있다. (파이썬에서 변수는 단순히 정보가 담긴 그릇을 의미하는 것이 아니다. 기능이 있다.)
  • 장점: 초보자라도 눈치껏 문법을 배우기 편하다.
  • 단점: 처음에는 너무 이해하기 난해함.

- 마음의 눈

  • a.f() = f(a) 로 생각하면 편리함
  • a.f(2) = f(a,2) 로 생각하면 편리함.
  • 이러한 점에서 R의 %>% 연산자와 유사하다고 생각할 수 있음 (사실 약간 다르긴해요)

- 리스트 특화기능 (=특화함수=메소드)

(append)

a.append?
Signature: a.append(object, /)
Docstring: Append object to the end of the list.
Type:      builtin_function_or_method
a=[1,2,3]
a.append(4)
a
[1, 2, 3, 4]

(clear)

a.clear?
Signature: a.clear()
Docstring: Remove all items from list.
Type:      builtin_function_or_method
a=[1,2,3]
a.clear()
a
[]

(copy)

a.copy?
Signature: a.copy()
Docstring: Return a shallow copy of the list.
Type:      builtin_function_or_method
a=[1,2,3]
b=a.copy()
b
[1, 2, 3]

(count)

a.count?
Signature: a.count(value, /)
Docstring: Return number of occurrences of value.
Type:      builtin_function_or_method
a=[1,1,2,3.14,3.14]
a.count(3.14)
2

(extend)

a.extend?
Signature: a.extend(iterable, /)
Docstring: Extend list by appending elements from the iterable.
Type:      builtin_function_or_method
a=[1,2,3]
b=[1,2,3,4,5,6]
a.extend(b)
a
[1, 2, 3, 1, 2, 3, 4, 5, 6]

(index)

a.index?
Signature: a.index(value, start=0, stop=9223372036854775807, /)
Docstring:
Return first index of value.

Raises ValueError if the value is not present.
Type:      builtin_function_or_method
a=[1,2,3,3,4,4,5,6]
a.index(5)
6

(insert)

a.insert?
Signature: a.insert(index, object, /)
Docstring: Insert object before index.
Type:      builtin_function_or_method
a=[1,2,3]
a.insert(0,88)
a
[88, 1, 2, 3]

(pop)

a.pop?
Signature: a.pop(index=-1, /)
Docstring:
Remove and return item at index (default last).

Raises IndexError if list is empty or index is out of range.
Type:      builtin_function_or_method
a=[1,2,3,4]
a.pop()
a
[1, 2, 3]
a.pop()
a
[1, 2]
a.pop()
a
[1]
a.pop()
a
[]

(remove)

a.remove?
Signature: a.remove(value, /)
Docstring:
Remove first occurrence of value.

Raises ValueError if the value is not present.
Type:      builtin_function_or_method
a=[1,2,3,44]
a.remove(44)
a
[1, 2, 3]

(reverse)

a.reverse?
Signature: a.reverse()
Docstring: Reverse *IN PLACE*.
Type:      builtin_function_or_method
a=[1,2,3]
a.reverse()
a
[3, 2, 1]

(sort)

a.sort?
Signature: a.sort(*, key=None, reverse=False)
Docstring:
Sort the list in ascending order and return None.

The sort is in-place (i.e. the list itself is modified) and stable (i.e. the
order of two equal elements is maintained).

If a key function is given, apply it once to each list item and sort them,
ascending or descending, according to their function values.

The reverse flag can be set to sort in descending order.
Type:      builtin_function_or_method
a=[1,3,2,4]
a.sort()
a
[1, 2, 3, 4]

리스트공부 3단계

리스트의 뺄셈과 나눗셈

- 리스트의 뺄셈: 이런건 없다.

a=[1,2,3,4]
a-[1]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-178-fcd9077664c1> in <module>
      1 a=[1,2,3,4]
----> 2 a-[1]

TypeError: unsupported operand type(s) for -: 'list' and 'list'

- 리스트의 나눗셈: 이런건 없다.

a=[1,2,3,1,2,3]
a/2 
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-179-0f405c3ca648> in <module>
      1 a=[1,2,3,1,2,3]
----> 2 a/2

TypeError: unsupported operand type(s) for /: 'list' and 'int'

a.append(4) 와 a+[4] 의 차이점?

- a=a+[4]: a는 변화하지 않음.

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

- a.append(4): a자체가 변화함

a=[1,2,3]
a.append(4)
a
[1, 2, 3, 4]

- 보통 메소드를 쓰면 a자체가 변화할때가 많다.

a=[1,2,3]
a.reverse()
a
[3, 2, 1]

- 그런데 모든 메소드가 a를 변화시키는 것은 아니다. (명확한 기준은 없는데 왠지 의미상 a를 변화시킬 필요가 없을 것 같은게 있어요..)

a=[1,2,2,3,4]
a.count(2) 
2
a
[1, 2, 2, 3, 4]

len은 list의 원소를 세어서 리턴한다.

a=[1,2,3,3]
len(a) 
4
a=[]
len(a)
0

- 아래는 동작하지 않음.

a=[1,2,3]
a.len()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-192-0f2df5fcd2b1> in <module>
      1 a=[1,2,3]
----> 2 a.len()

AttributeError: 'list' object has no attribute 'len'

[3]과 3은 다르다

- 다른점1: [3] 1차원, 3은 0차원 자료형

a=[3]
len(a)
1
a=3
len(a)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-195-ef5c313af7eb> in <module>
      1 a=3
----> 2 len(a)

TypeError: object of type 'int' has no len()

- 다른점2: +연산 적용시 차이점

a=[3]
a+[4]
[3, 4]
a=3
a+4
7
a=[3]
a+4
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-198-51cc563c823d> in <module>
      1 a=[3]
----> 2 a+4

TypeError: can only concatenate list (not "int") to list
a=3
a+[4]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-199-62e0fc93f386> in <module>
      1 a=3
----> 2 a+[4]

TypeError: unsupported operand type(s) for +: 'int' and 'list'

리스트의 원소는 어떠한 형태도 가능하다.

- 예제1

a=[True,3,3.14]
a
[True, 3, 3.14]
type(a[0])
bool
type(a[1])
int
type(a[2])
float

예제1에 대한 디스커션

  • 리스트에 포함된 3개의 원소가 모두 다른 자료형을 가지고 있음.
  • 즉 원소들이 형변환 되지 않음. (Python의 list는 R에서의 벡터보다 리스트에 가까운 느낌이다)

- 예제2

a=[[True,3,3.14],True,[3],3]
a
[[True, 3, 3.14], True, [3], 3]

예제2에 대한 디스커션

  • 첫번째 원소는 리스트 (1차원)
  • 두번째 원소는 bool (0차원)
  • 세번째 원소는 길이가 1인 리스트 (1차원)
  • 네번째 원소는 int (0차원)

중첩리스트

A=[[1,2,3],[4,5,6],[7,8,9]]
A
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

- A는 아래와 같은 매트릭스로 생각할 수 있다.

${\bf A} = \begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \end{bmatrix}$

- ${\bf A}$에서 (1,1)의 원소를 뽑고싶다! = 1을 뽑고싶음

A[0,0] 
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-210-da4621a80edb> in <module>
----> 1 A[0,0]

TypeError: list indices must be integers or slices, not tuple
  • 실패
A[0][0]
1
  • 성공

- 성공의 이유분석

A
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
A[0]
[1, 2, 3]
A[0][0]
1

- ${\bf A}$에서 (2,3)위치의 원소를 뽑아보자. $\to$ 파이썬 인덱스로 치면 (1,2)

A[1][2]
6

- 매트릭스는 아니지만 매트릭스 같아!

1차원 배열을 다차원 배열로 확장할 수 있는 기본아이디어를 제공함

튜플공부 1단계

- 튜플은 ()로 선언한다.

a=(1,2,3) 
a
(1, 2, 3)
type(a)
tuple

- +로 튜플과 튜플을 합칠 수 있다.

a=(1,2,3)
b=(4,5,6)
a+b
(1, 2, 3, 4, 5, 6)

- 비어있는 튜플을 선언하는 방법

a=tuple()
a
()
a=()
a
()

- 원소가 하나있는 튜플을 만들기 위해서는 아래와 같이 한다.

a=(1,)
a
(1,)
a+(2,)
(1, 2)

- 튜플도 리스트와 비슷한 방식으로 원소에 접근한다.

a=(1,2,3)
a[0]
1
a[1]
2
a[2]
3

- 튜플은 원소에 접근할 수는 있지만 내용을 바꿀 수는 없다.

a=(1,2,3)
a[0]
1
a[0]=100
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-232-f96ffea17930> in <module>
----> 1 a[0]=100

TypeError: 'tuple' object does not support item assignment

- 예제: 빈튜플을 만들어보고 (1,) (2,) (3,) 을 더하여 원소를 추가해보자.

a=()
a
()
a=a+(1,)+(2,)+(3,)
a
(1, 2, 3)

- 아래와 같은 방식도 가능

a = ()
a += (1,)
a += (2,)
a += (3,)
a 
(1, 2, 3)

튜플공부 2단계: 튜플 언패킹

- 의미가 명확할때는 ()를 생략할 수 있다.

a = 1,2,3,4,5
a
(1, 2, 3, 4, 5)
1,2,3 
(1, 2, 3)

1차원자료형의 변환

- 리스트를 튜플로

tuple([1,2,3])
(1, 2, 3)

- 튜플을 리스트로

list((1,2,3))
[1, 2, 3]

numpy

파이썬은 그렇게 좋은 계산성능을 보유하고 있지 않음

- 놀라운점1: pi가 없음

pi
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-241-f84ab820532c> in <module>
----> 1 pi

NameError: name 'pi' is not defined

- 놀라운점2: sqrt가 없다.

sqrt(2)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-242-66e338417901> in <module>
----> 1 sqrt(2)

NameError: name 'sqrt' is not defined

- 사칙연산빼고 되는게 없는것 같은데?

log(10) 
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-243-8fe8026424a0> in <module>
----> 1 log(10)

NameError: name 'log' is not defined
exp(1)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-244-a9c50c82dfa5> in <module>
----> 1 exp(1)

NameError: name 'exp' is not defined
sin(0)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-245-afbcc558f753> in <module>
----> 1 sin(0)

NameError: name 'sin' is not defined

numpy를 쓰면 파이썬은 좋은 계산기가 된다.

  • 사용법: library(tidyverse)와 비슷하게 import numpy 를 하면 된다.
import numpy
numpy.pi
3.141592653589793
numpy.sqrt(2)
1.4142135623730951
numpy.exp(1)
2.718281828459045
numpy.log(2.718281828459045)
1.0
numpy.sin(0)
0.0

- numpy를 모두 치는 것이 불편함 $\to$ 줄여서 약어로 쓰고싶다.

import numpy as np
np.sqrt(2)
1.4142135623730951
np.exp(1)
2.718281828459045
np.log(2.718281828459045)
1.0
np.sin(0)
0.0

numpy 공부: 1단계

- numpy.ndarray 자료형을 만드는 방법

a=[1,2,3]
b=np.array(a)
b
array([1, 2, 3])

- numpy를 사용하면 R과 유사한 환경이 만들어짐

a+1
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-265-98b939904c8e> in <module>
----> 1 a+1

TypeError: can only concatenate list (not "int") to list
b+1
array([2, 3, 4])
np.sqrt(b)
array([1.        , 1.41421356, 1.73205081])
np.log(b)
array([0.        , 0.69314718, 1.09861229])
np.sin(b)
array([0.84147098, 0.90929743, 0.14112001])
np.exp(b)
array([ 2.71828183,  7.3890561 , 20.08553692])
((b+1)+2)/3
array([1.33333333, 1.66666667, 2.        ])