https://proceedings.neurips.cc/paper/2012/file/c399862d3b9d6b76c8436e924a68c45b-Paper.pdf

오늘 review할 논문은 딥러닝의 시대를 열었다고 해도 되는 AlexNet입니다.

AlexNet은 2012년  ILSVRC(ImageNet Large-Scale Visual Recognition Challenge) 에서 우승하였습니다.

 

Abstract

ImageNet LSVRC-2010 대회에서 High resolution 이미지를 약 1000개의 다른 class로 분류 하기 위해
Deep Convolution neural network를 train 하였으며, test data에서 top-1 and top-5 error rates가 37.5% 및 17.5%를
달성 하였습니다. 이는 이전보다 발전한 상태입니다.

약 6천만개의 parameter와 65만개의 뉴런이 사용 됩니다. 그리고 5개의 convolutional layers를 가지며,  그 중에 일부는 max pooling layer를 가지고 있습니다.
그리고 마지막에는 3개의 fully-connected layer를 가지게 됩니다.
최종 layer 출력은 1000개의 softmax로 구성됩니다. train 속도를 위하여 non-saturation neurons과 효과적인 GPU 구현을 이용 하였습니다.
그리고 Overfitting을 줄이기 위하여 dropout 기법을 이용하여 regularization을 하였습니다. 

ILSVRC-2012 Contest에서 model을 변형하여 2등과 큰 차이로 우승 하였습니다.

역대 우승자

Datasets

imagenet

train에 사용된 데이터 셋은 imageNet 입니다.

imageNet 딥러닝의 대모이신 Fei Fei li 교수님이 만드신 걸로, 1500만개의 high resolution 이미지를 가지고 있으며 약 22000개의 category를 가지는 대규모 데이터 셋 입니다.

ILSVRC는 Imagenet 의 일부를 이용하는데, 카테고리가 약 1000개에 약 1000개의 이미지가 있는 것을 이용합니다.

imageNet는 총 120만개의 train, 50000개의 valid, 150000개의 test image가 있습니다

imageNet은 이미지 크기가 다양 하므로 이미지 크기를 256*256으로 고정 하였습니다.

왜냐하면 나중에 Fully-connected layer로 입력시 크기가 고정 되어야 하기 때문입니다.

resize는 width height중에 짧은 곳을 256으로 변환, 그리고 center부분을 256 으로 cropped 하였습니다.

그리고 각 image의 pixel에서 traning set의 mean을 빼주었습니다.

그 외에는 데이터 pre-process를 하지 않았습니다.

 

Architecture

Network architecture의 요약은 논문의 Figure 2에 있습니다.

Alexnet 구조

차근차근 하나하나 자기들이 설정한 기법에 대해서 설명합니다.

ReLU Nonlinearity

cs231n Activation Functions

보통 평범한 방법으로 각 neuron 의 output은 tanh, sigmoid방식이 있습니다.

하지만 뭐. cs231n을 들은 사람은 알겠지만, 이 두개 방식은 sigmoid는 mean이 0이 아닌것, tanh는 이를 해결 하였지만

두개다 가지고 있는 고질적인 문제는 Saturated Neurons kill gradient 같은 문제가 있습니다.

그래서 Rectified Linear unit을 사용 합니다.

이는 Deep convolutional neural netwrok에서 tanh units보다 빠르게 작동합니다.

상식적으로 생각을 해봐도 max(0,x)보다 tanh가 더 계산량이 많다고 생각을 할 수 있을거같긴 하다.

CIFAR-10에서 결과

CIFAR-10 Dataset에서 검증한 결과로 CIFAR-10은 10개의 카테고리 50000장의 Train, 10000장의 Test image가 있는 것 입니다. 그래프에서 보면 점선은 tanh이고, 실선은 ReLU입니다.

Epoch가 진행 될 수록 시간차이가 심해지는 것을 알 수 있습니다.

25% training error 까지 약 눈대중으로 보기에는 6~7epoch와 37epoch정도 같으니 약 6배정도 차이가 나는 것을 알 수 있습니다.

Training on Multiple GPUs

3GB메모리 용량

2012년 당시 GPU는 GTX580이였다.

Memory 용량이 3GB 파멸적인것을 알 수 있습니다.

Network를 train 시키기에는 부족한 양이라 여기서는 두개의 GPU를 이용하여 Training 하였습니다.

위에 그림을 보면 중간에 두개로 나눠지는 이유가 그러한 이유입니다. 

Host를 거치지 않고 두개가 서로의 메모리에 접근이 가능하고, 두개의 GPU는 특정 Layer에서만 교환합니다.

 

Local Response Normalization

LRN

Relu가 gradient Saturation을 막는데 많이 도움이 됩니다.

하지만 이 방식의 normalization도 크게 도움이 되는데, Relu에나 나온 결과들을 같은 Spatial 위치의 인접한 Kernel map n개를 모아서 정규화 합니다. 요새는 안쓰는 방법이므로 심도 있게 알고 싶다면 검색하는 것을 추천드립니다.

현재는 Batch normalization을 사용합니다. 

 

Overlapping Pooling

정통적인 방식은 겹치게 안했습니다.

Alexnet은 pooling size = 3, stride =2 즉 CNN에서 서로 Overlapping된는 max pooling을 수행 하였고, overfitting을 

방지하는데 도움이 된다고 하였습니다. 실제로 top-1 top-5에서 error rate가 0.4, 0.3감소 한다고 하며, 다음과 같이 train중에 overlapping pooling이 존재하면 overfit이 어렵다고 합니다.

 

Overall Architecture

Alexnet 구조

순서대로 정리 하겠습니다.

cs231n에서는 227*227*3 input이 맞네요. 왜냐하면 정상적으로 하였을때 227 이여야 한다니. 논문의 오류

간단하게 계산 하는 법은 (input - Filter size + 2*padding) / Stride + 1 입니다

[INPUT]

227*227*3 Size image

 

[CONV1]

96 11*11 Filter, Stride 4, Pad 0

INPUT : 227*227*3

OUTPUT : 55*55*96

 

[MAX POOL1]

3*3 Filter, Stride 2

INPUT : 55*55*96

OUTPUT : 27*27*96

 

[NORM1]

LRN 을 이용

INPUT : 27*27*96

OUTPUT : 27*27*96

 

[CONV2]

256 5*5 Filter, Stride 1, Pad 2

INPUT : 27*27*96

OUTPUT : 27*27*256

 

[MAX POOL2]

3*3 Filter, Stride 2

INPUT : 27*27*256

OUTPUT : 13*13*256

 

[NORM2]

LRN 을 이용

INPUT : 13*13*256

OUTPUT : 13*13*256

 

[CONV3]

384 3*3 Filter, Stride 1, Pad 1

INPUT : 13*13*384

OUTPUT : 13*13*384

 

[CONV4]

384 3*3 Filter, Stride 1, Pad 1

INPUT : 13*13*384

OUTPUT : 13*13*384

 

[CONV5]

256 3*3 Filter, Stride 1, Pad 1

INPUT : 13*13*256

OUTPUT : 13*13*256

 

[MAX POOL3]

3*3 Filter, Stride 2

INPUT : 13*13*256

OUTPUT : 6*6*256

 

[FC1]

INPUT : 6*6*256

OUTPUT : 4096

 

[FC2]

INPUT : 4096

OUTPUT : 4096

 

[FC3]

softmax

INPUT : 4096

OUTPUT : 1000

 

Reducing Overfitting

AlexNet은 600만개의 Parameter가 있으므로 Overfitting을 피하기 위해 몇가지 기법을 사용 하였습니다.

Data Augmentation

제일 쉬운 방법으로 overfitting을 피하는 방법으로 데이터의 양을 늘리는 것 입니다.

작은 연산으로 image Augmentation이 가능하기 때문에 GPU가 학습하는 동안 CPU가 Python code로 mini batch의 Augmentation을 진행 합니다.

반전

가장 쉬운 방식은 반전 시키기 방식 입니다.

random crops

이미지 원본데이터에서 무작위로 이동하여 이미지를 추가하는데, 256*256 이미지 경계 내부에서 227*227 크기로 무작위로 자른 뒤에 추출이미지를 딥러닝 학습으로 이용 하였습니다. 이 방법으로 2048배 늘렸습니다.

자세히 보면 조금씩 다른 것을 알 수 있습니다.

PCA COLOR SHIFT

PCA color Augmentaton이란 dataset에서 RGB채널을 바꾸는 것 입니다.

PCA 주성분 분석을 통해 이미지 특성은 유지하지만 RGB값은바꾸는 것 입니다.

사실 PCA부분은 잘 모르겠네요 조만간 공부해서 POST 하겠습니다.

Drop out

FC Layer의 부분에서 drop 아웃을 진행합니다.  drop out의 확률은 0.5로 설정 하였으며, forwardpass와 backwardpass시 영향을 끼치지 않습니다. 매 입력마다 적용하여 가중치는 공유하지만 서로다른 구조를 가지게 됩니다.

이러한 방식으로 Overfitting을 방지합니다.

 

Details of learning

최적화 식

AlexNet에 사용된 것 입니다.

momentum=0.9, batch size=128, weight decay=0.005, SGD Momentum 를 사용 하였습니다

Weight초기화는 mean 0, std 0.01 가우시안 분포를 이용 하였습니다.

bias는 conv2,4,5와 FC에서는 1, 나머지는 0으로 하였습니다.

learning rate는 1e-2로 하였으며 validation error가 높아지지 않으면 10으로 나눠가며 하였으며, 총 3번 감소 하였습니다.

 

틀린부분이 있다면 댓글로 알려주시면 감사 하겠습니다.

* 공부한 내용 뇌피셜로 정리 *

출처 : https://arxiv.org/abs/2004.10934

object detecion모델을 사용해보거나 논문을 읽어본 사람은 다음과 같은 그림을 본적이 있을것이다.

아무것도 모르고 본 상태에서 직관으로는 AP와 FPS가 모두 높아야 좋은 모델이란 것을 생각 할 수 있다.

위에서 부터 단어의 정의를 하나씩 정리하는 방향으로 가는 것이 좋을 것 같다.

보통 object의 성능을 평가하는 요소들은 IOU, Precision-Recall Curve, Average precision, Confidence threshold가 사용 됩니다. 

mAP (mean Average precision) 란?

실제 object detect된 recall과 presion의 값을 평균한 성능 수치 입니다.

출처 : https://machinelearningmastery.com/roc-curves-and-precision-recall-curves-for-imbalanced-classification/

다음과 같은 recall, precision 그래프의 아래의 면적을 평균을 취한 것이 mAP라고 이해하면 됩니다.

여기서 Recall과 Precision에 대하여 궁금증이 생기게 됩니다.

보통 Precision과 Recall 은 이진분류에 사용되는 성능 지표입니다.

Precision 이란?

한국어로는 정밀도 라고 하며 이는 검색된 결과들 중에 관련이 있는 것으로 분류된 결과들 중 관련있는 것으로 분류된 결과물의 분류

Recall 이란?

한국어로는 재현율 라고 하며 이는 관련 있는 것으로 분류된 항목들 중 실제 검색된 항목들의 비율이다.

https://ko.wikipedia.org/wiki/%EC%A0%95%EB%B0%80%EB%8F%84%EC%99%80_%EC%9E%AC%ED%98%84%EC%9C%A8

 

대부분의 사람이 글로 보면 이해하기 어려울 것 이라고 생각합니다.

https://ko.wikipedia.org/wiki/%EC%A0%95%EB%B0%80%EB%8F%84%EC%99%80_%EC%9E%AC%ED%98%84%EC%9C%A8
계산하는 방식

Object detecion에서 사용하는 방식으로 설명을 하겠습니다.

Object detecion에서는 어떤 물체를 예측하면 bbox를 치게 됩니다.

TP

간단하게 bbox에서 정확하게 예측한 경우

FP

bbox를 생성하긴 하였지만 예측을 정확하게 못한경우 , class가 틀린 경우, IOU가 낮은 경우, Overlap이 일어나지 않은 경우 

FN

아예 object가 있는 곳에 bbox를 생성하지 않은 경우

쉽게 생각하여 Precision은 bbox를 생성 한 것들 중에 정확하게 예측한게 몇개있냐,

Recall은 기존에 annotation한 object 중에 몇개를 정확하게 예측하였냐 입니다.

 

업무에 따라서 Recall 과 Precision의 값을 잘 선택 하셔야 한다.

Recall이 중요한 경우는 양성이 중요한 것을 음성으로 판단하여 업무상 큰 재해가 발생하는 경우 입니다.

즉 암진단 같은 경우 Recall이 낮아지면 암이 지만 잘못된 판단을 할 수도 있습니다.

Precision이 중요한 경우는 음성인 데이터를 양성으로 판단하는 경우 입니다.

즉 스팸메일 같은 경우 음성인 데이터를 양성으로 판단하여 걸러버리면 업무상에 문제가 발생 할 수 있습니다.

정밀도와 재현율을 적절한 값으로 구하는 것이 중요 합니다.

 

confidence threshold값에 따라 Precision과 recall값이 크게 변하게 됩니다.

confidence threshold는 특정 임계값을 넘으면 bbox를 생성 하도록 하는 것 입니다.

간단하게 생각하여 Confidence threshold가 낮으면 많은 bbox가 생성되어 Precision은 낮아지고, Recall은 높아집니다.

만약 높아지면 bbox가 신중하게 생성되어 Precision은 높아지고, Recall은 낮아집니다.

이 두값은 서로 상호보완적인 관계 이므로 confidence threshold를 바꾸며 관찰하면 한쪽이 높아지면 다른쪽이 낮아지는 현상이 발생합니다.

이는 Trade off현상이라고 생각하면 됩니다.

Confidence Threshold를 조절하여 생성한 Precision-Recall curve를 이용하여 아래의 면적을 계산하면 AP가 되게 됩니다.

 

AP는 한개의 Object에 대한 성능 수치로 mAP는 여러 Object들의 AP를 평균하여 구해게 됩니다.

 

PASCAL VOC같은 경우 IOU가 0.5이상으로 mAP를 구합니다.

COCO같은 경우 다양한 경우로 AP를 구하는데 상당히 까다롭게 하게 됩니다. 

 

COCO YOLOV2

 

PASCAL VOC

 

* 공부한 내용 뇌피셜로 정리 *

Non max suppression 기법

Non max suppression 기법은 Object detection 알고리즘에서 사용되는 방법중 하나 입니다.

Object detection은 있을만한 위치를 모두 예측 하므로 위에 그림과 가이 겹치는 bounding box가 많아 집니다.

이렇게 겹치는 bounding box가 많을때 비슷한 것을 제거하고 가장 적합한 것을 선택하는 기법입니다.

NMS수행 로직은 어렵지 않습니다.

 

1단계

Object detected 된 bounding box에서 사용자가 설정한 confidence threshold이하인 bounding box는 모두 제거 합니다. 즉 이용자가 threshold를 0.6 으로 정하면 0.6 이하는 모두 제거합니다.

2단계

confidence score별로 내림차순을 적용합니다.

3단계

confidence score가 높은 놈들과 겹치는 다른 box는 모두 제거 하는데, 이용자가 정한 특정한 IOU Threshold 이상인 것들은 모두 제거 합니다. 즉 IOU값은 0.5로 정하면 0.5 이상은 모두 제거합니다.

4단계 

남아있는 BBOX를 선택합니다.

* 공부한 내용 뇌피셜로 정리 *

Intersection over union은 model이 예측한 결과와 ground truth 실측 box가 얼마나 겹치는 가에 대한 지표 입니다. 

간단하게 그림과 같이 생각 할 수 있습니다. 겹치는 영역 / 전체 box 영역 입니다.

값의 범위는 0~1로 1에 가까울수록 예측을 잘한 것 이라는 것을 알 수 있습니다.

IOU는 코드로 간단하게 구현이 가능한데 다음과 같이 구현 하였습니다.

IOU를 간단하게 구현하고 예를 들기 위해 저번 포스팅에서 실습한 Selective Search를 활용 하였습니다.

 

https://inha-kim.tistory.com/37?category=963044 

 

[컴퓨터 비전] Sliding window 대한 내용, Selective Search 사용 및 시각화

* 공부한 내용 뇌피셜로 정리 * 컴퓨터 비전에서 Sliding Windows방식은 Object Detecion에 아주 초기 기법으로 사용된 방식이다. 사용방법은 다양한 크기의 Windows(보통 사각형 모양)을 이미지에서 이동시

inha-kim.tistory.com

내용이 궁금한 분은 들어가 보세요.

필수 패키지 import

필수 패키지 import합니다. selective search 이후의 code입니다.

 

opencv로 데이터 시각화

ground truth영역을 임의로 정한 뒤에 ground truth box는 red로, selective search 로 구한 영역을 초록색으로 표현 

하였습니다.

출력결과 

코드 실행 결과는 다음과 같습니다. 빨간색이 실제 영역, 나머지는 예측 영역.

iou를 계산하는 코드

iou계산은 다음과 진행됩니다.

교차 영역 /예측영역 + 실제 영역 - 교차 영역 

교차영역은 왼쪽 위 꼭지점, 아래 꼭지점을 구하여 넓이를 구할 수 있습니다. 이때 만약 교차하지 않으면 겹치는 영역은 0으로 됩니다.

iou를 출력하는 코드

iou를 출력하는 코드는 enumerate를 이용하여 index와 cand_box로 rects를 전달합니다.

rects에서 전달받은 좌표값을 살짝 가공 해야하는데 selective search에서 나온 값은 왼쪽 위 꼭지점 + 너비와 높이 값 이므로 오른쪽 아래의 좌표는 각각 cand_box[2]와 cand_box[3]에 cand_box[0,1] 값을 더해서 compute_iou에 전달합니다.

계산된 iou

iou값을 시각화를 진행 하여 보겠습니다.

iou가 0.5 이상인 값들만 시각화를 진행 하였습니다.

iou 0.5이상에 박스 추가

다음과 같이 iou가 0.5이상일 경우 rectangle과 putText를 추가 하였습니다.

출력결과

전체 코드는 다음과 같이 코랩에 있습니다.

https://colab.research.google.com/drive/1HtS-UsIrCRkn3gQE4xSVjcHV8en4WHyX?usp=sharing 

 

IOU.ipynb

Colaboratory notebook

colab.research.google.com

 

* 공부한 내용 뇌피셜로 정리 *

컴퓨터 비전에서 Sliding Windows방식은 Object Detecion에 아주 초기 기법으로 사용된 방식이다.

사용방법은 다양한 크기의 Windows(보통 사각형 모양)을 이미지에서 이동시켜가면서 객체가 있을법한 위치를 찾는방법

하지만 이 방식은 여러개의 Window사이즈, 그리고 이미지 사이즈를 이용하여 찾아야 다양한 크기의 객체를 찾을 수

있어 모든 경우를 따져야 하므로 수행시간도 오래 걸리고, 생각보다 적절한 검출이 어렵다.

그래서 탄생한 방식이 위와같이 모든 경우를 탐색하는 방법보다는 Region Proposal 영역추정 Object가 있을 만한 곳을 추정하자는 방식이 나오게 되었다.

여기서 나온 알고리즘이 Selective Search 이다.

Selective Search는 객체가 있을 만한 곳을 탐지하는데 이때 어떻게 탐지하느냐, Color,Size,Texture,Shape에 따라 Segmentaion을 적용하는데, 이때 심각하게 Over Segmentation이 발생 하는 경우도 발생 하는데 이걸 그대로 사용하는 것이 아니라 주변의 Color,Size,Texture,Shape가 유사한 것 들 끼리 grouping을 반복하여 Region Proposal을 반복 합니다. 그러면 처음에 Raw하게 Segmentaion 한 것 보다는 적은 Bounding box를 얻을 수 있습니다.

 

 

 

https://colab.research.google.com/drive/18yMw5pe0vR_0mtwVcTkfEA5aOjdwMUnB?usp=sharing 

 

Selective_Search.ipynb

Colaboratory notebook

colab.research.google.com

간단하게 있는 패키지를 이용하여 실습을 진행 하였습니다.

인공지능이란?(AI)

인간의 학습,추론,지각 능력을 인공적으로 구현하는 컴퓨터 과학의 분야이다. 하나의 인프라 기술

즉 사람의 지능을 만들기 위한 프로그램이다.

 

여기서 인공지능은 Strong AI와 Weak AI두개로 나눠진다.

Strong AI 같은 경우 사람과 구분이 불가능 할 정도의 강한 성능을 가진 인공지능, 즉 아이언맨의 쟈비스, 그녀(Her)에 나온 인공지능들을 말합니다. 매우 만들기 어려우며 , 기술이 출시되는 시기가 언제일지 알기도 어려울 정도 입니다.

 

Weak AI 같은 경우에는 사진에서 물체를 찾는거나, 소리를 듣고 상황 파악  같이 인간이 쉽게 해결이 가능하지만 

컴퓨터로 처리하기에는 어려웠던 문제를 컴퓨터로 수행하게 만드는 것에 중점을 두고 있는 것 입니다. 

즉 특정한 영역에서 작업을 수행하는 인공지능입니다. 자율주행 운전 보조, 질문 답변 같은 일들을 처리 합니다.

현재 나온 것으로는 테슬라의 자율주행, 시리, 빅스비 등이 있습니다.

 

현재 나온 대부분의 기술은 약인공지능 기술이며 현재 생활에 많은 부분에 사용 되고 있습니다. 

 

머신러닝, 딥러닝, 인공지능의 관계는 어떠한가?

다음과 같은 관계를 가진다는 것으로 이해 하면된다.

AI, 머신러닝, 딥러닝의 관계

다음과 같은 관계를 가지므로 머신러닝을 잘 이해해야 딥러닝을 할 수 있습니다.

 

선형회귀(Linear regression),경사하강법(gradient descent)

Linear regression은 머신러닝 알고리즘 중 하나이며, 1차함수를 사용할 때는 2차원에서 평면에 놓인 점을 찾는데 사용

됩니다. 이것으로 x,y값을 예측이 가능합니다.

당뇨병환자 데이터 셋에대한 Linear regression. 사이킷런에 있는 당뇨병환자 데이터 셋을 사용함.

최적화 알고리즘 경사하강법(gradient descent)이용

경사하강법이란 기울기를 사용하여 모델을 조금씩 조정하는 최적화 알고리즘입니다.  

보통 예측값으로 올바른 모델을 찾는 방법은

1. weight와 bias를 정한 뒤에 모델을 예측

2. 샘플로 결과 구한 뒤, target과 비교,

3. target과 가까워지도록 weight와 bias를 조정

4. 모든 샘플에 대해서 다음과 같이 수행

 

CS231n 강의 공부

Chapter1은 간단한 컴퓨터비전 소개 ,

Chapter2는 고전적인 Image classification pipeline에 대한 소개 였다.

 

 

이번에는 Chapter 9까지 스터디를 진행 하였다.

http://www.yes24.com/Product/Goods/29289816

 

처음 시작하는 파이썬 - YES24

파이썬으로 프로그래밍에 입문하자!데이터 분석, 금융, 자연 과학 등 다양한 분야에서 각광받는 언어 파이썬. 개발자가 아니더라도 개발자가 되고 싶다면, 개발자지만 파이썬을 처음 시작한다

www.yes24.com

책의 구매 링크이다.

https://inha-kim.tistory.com/34

 

[처음 시작하는 파이썬] 2주차 스터디 정리 [반복문: while과 for 문], [튜플과 리스트], [딕셔너리와

이번에는 Chapter 6 부터 Chapter 8 까지 스터디를 진행 하였다. http://www.yes24.com/Product/Goods/29289816 처음 시작하는 파이썬 - YES24 파이썬으로 프로그래밍에 입문하자!데이터 분석, 금융, 자연 과학 등..

inha-kim.tistory.com

지난주 스터디 결과이다.

코드를 반복하는 것은 매우 비효율 적이다. 
코드를 재사용 하기 위해 탄생한 것이 함수이다.
파이썬에서 함수는 parameter(매개변수)로 모든 타입을 취할 수 있다.


함수 정의는 def로 한다.
괄호안에 option으로 매개변수를 줄 수도 있지만, 안줄수도 있다.
이름 규칙은 변수와 동일하다.
매개 변수가 없는 함수를 호출하면 다음과 같다.

매개 변수가 없으며, 아무것도 하지 않는다는 pass

함수 호출은 다음과 같이 수행한다.
그냥 함수 이름을 쓰면 된다.
위에 예제는 return이 없으므로 none이 return 된다.
함수를 호출 하면 다음과 같이 함수 안에 문장이 실행 된 뒤에 다시 돌아간다.

다음과 같이 함수 호출

다음과 같이 return을 줄 수도 있다.

간단한 if문을 check

한번 def ~~~()에 간단하게 매개변수를 줄수 있다.

echo 함수에 김현우를 전달 하자 my name is 김현우가 출력

여기서 코딩? 하는 사람들이 은근 햇갈리는게 하나 있다. 매개변수(parameter)와 인수(argument)를 오해하는 경우가 
있다.
매개변수란 함수 내부에선 매개변수이다. 하지만 함수 외부에서 전달할때는 그것은 인수이다.
즉 def echo(name)에서 name은 매개변수, print에서 김현우는 인수이다.

다음과 같이 색을 test하는 함수도 만들 수 있다. 여러가지 색을 test할때 저거 if문을 도배 하는 것이 아닌
저거 하나만 가져다 쓰면 된다.

만약 함수를 쓰지 않는다면 코드가 더 길어지고 피곤해진다.

return 값은 변수에 전달이 가능하다. 하지만 return이 없다면 None이 return 된다.

return이 있으므로 what_color에 결과가 저장 된다. return 없으면 None

None은 파이썬에서 좀 특별한 값이다. 뭔가 False 같아 보이지만 다른 값을 의미한다.

None과 False는 다르다.

그럼 False와 None으로 어떻게 구분할까 바로 is 연산자를 사용하면 된다.

is를 이용하여 None을 체크 한다.

한번 다음과 같이 None, False, True를 한번 test해보자. 함수를 만든다

다음과 같다.

한번 다양한 것들을 체크 해보자.

빈 자료구조와 str은 False이다.

파이썬은 다른 언어에 비해 인수 처리가 매우 유연,독특하다. 
매개 변수에 복사하는 위치인수이다. 가장 익숙한 방식이다.
다음과 같은 함수는 3개를 매개변수로 전달 받는다.

순서에 따라서 전달 받는다.

여기서 이런 방식은 항상 매개변수의 위치를 알아야 한다.

 

이러한 방식을 보완하는 방식은 키워드 인수 방식이다.
다음과 같이 하며 순서가 바껴도 상관없다.

다음과 같이 high와 middle의 위치가 바껴도 출력이 똑같다.

매개변수에서 기본값을 지정 할 수도 있다.
처음에는 암것도 안준것, 두번째는 초등학교만 인하를 준 것이다.

다음과 같이 기본 값을 줄 수 있다, 인수를 전달 안하면 기본값이 전달된다.

여기서 조심히 봐야할 게 있다.
파이썬의 특징이자 기술면접에 가끔 나온다고 한다.

지역 변수가 아닌 것을 알 수 있다. 예상한 결과가 ㅏ아니다.

우리가 예상한 결과는 ['a'], ['b']이지만 아니다.
예상한 결과를 만드는 법은 다음과 같다.

우리가 예상한 결과가 나오는 것을 알 수 있다.

 

*는 C/C++에서는 포인터로 생각 할 수 있지만, 파이썬은 포인터가 없다.
함수의 매개변수 * 에스터리스크를 사용하면 위치 인수 변수를 Tuple로 묶는다.
다음 예시를 확인하자.

인자의 개수를 마음대로 전달 할 수 있다.

이것은 다음과 같이 몇개의 인수는 의도적으로 따로 취할 수 있다.

num1과 num2에서 인수를 취하고, 나머지는 args로 처리한다.

*args를 사용 하는 이유는 그냥 이름이다. args는 관습적으로 쓰는 표현이다. 

두개의 차이를 확인 하자.

*구문은 함수호출 정의만 사용이 가능하다 아니면 error가 발생한다.

키워드 인수 분해 및 모으기는 **두개를 사용한다.
인수의 이름은 key, 이 값은 이 키에 대응하는 딕셔너리 값이다.

다음과 같이 딕셔너리 형태로 저장된다.
위에 args와 비슷하게 생각 할 수 있다.

키워드 전용 인수로 다음과 같이 start end 위치를 정할 수 있다. python3에서 부터 지원한다.
다음 예시를 확인하자.
이름에서 알 수 있듯, 위치적으로 제공이 아니라 이름=값으로 제공해야한다. *는 start.end를 사용하지 싶지 않으면
인수로 제공해야한다.

다음과 같이 원하는 인수를 취할 수 있다.
이렇게 주는 것은 error가 발생한다. 꼭 이름=값으로 전달 해야한다.


가변 인수인 리스트는 함수 안에서 바뀔시에 밖에있는 것도 바뀔까? 한번  test해보자.
아주 안좋은 것으로, 함수 내에서 인수가 바뀐다고 문서화하거나 새값을 반환해야한다.
함수내부에서 변하는 것에 대해서 주의하자.

이건 매우  안좋은 예이다. 외부가 내부에서 바뀜

독스트링이라는 파이썬의 독특한 것이 있다.
문자열을 포함시켜 함수 정의에 문서를 붙일 수 있다.
다음 예제를 확인하자.

함수에 대한 설명이 가능하다. 유용한 기능이다.

이러한 방식으로도 가능하다.

이렇게 파이썬에 사용자 정의 함수에 주석을 달 수 있다.

모든것은 객체이다. 파이썬의 철학이다.
객체에는 숫자 문자열 튜플 함수까지 모든 것을 포힘한다.
파이썬은 다른언어에서 구현하기 힘든 것도 구현한다. 다음 예를 보자.

매우 간단한 함수이다.

다음과  같이 함수를 실행하는 함수가

있다고 할때 이와 같이 전달하면 answer함수가 실행 되는 것을 알 수 있다.

다음과 같이 가능하다.

여기서 함수의 type은 class 'function'이다.
다음과 같이도 가능하다.

add, run_somthing 함수, add 3 4 를 전달하면 7이 나온다.

그러면 앞에서 배운 *args 와 **kwargs도 가능할까? 그렇다 가능하다.

다른예도 많지만 이게 간단하다.

함수를 리스트, 튜플, 셋, 딕셔너리의 요소로 사용이 가능 하지만, 불변이기 때문에 딕셔너리 key로는 불가능 하다.


함수안에 함수를 정의 할 수도 있다. 좀 신기한 기능 처럼 보이긴 한다.
내부 함수는 주로 복잡한 작업을 한번이상  할떄 이용한다.

out_func에서 in_func(a+b)를 return 한다.

이런거로 쓰면 좋을거 같긴 하다.

간단한 예제이지만 함수 내에서 반복하면 쓰면 될거같다.

내부함수는 클로저로 동작 할 수 있습니다.
다른 함수에 의해 동적으로 생성 됩니다.
클로저에 속한 지역변수는 바깥에서 접근 할 수 없어서 데이터를 숨기고 싶을때 사용 합니다.
외부 함수로 부터 생선된 변수값을 저장 할 수 있는 함수입니다.

a,b,의 type은 function, a(),b()를 하면 출력이 함수에 전달되어 사용된 name을 기억한다. 출력이 잘 나오는 것을 알 수 있다.


익명함수는 lambda이다.
파이썬의 람다 함수는 단일문장으로 표현이 가능한 익명함수 입니다.

이런 간단한 code를 참고하자

lambda 를 사용하면 다음과 같이 가능하다. 좀 극단적인 예 인거 같지만

처음보면 많이 이상해 보인다.

뭐 설명없이 보면 좀 이상해보이긴한다.
람다는 쉽게 설명하면 콜론 : 이후에 함수를 정의한다.
all upper를 사용하는 것 보다 명확하며, 람다는 많은 작은 함수를 정의하는데 사용된다.
이런 예를 확인해보자.

첫 글자를 대문자로.
숫자

간단하게 한 줄로 간단한 기능을 하는 함수를 만들  수 있다.

제네레이터(generator)는 시퀀스를 생성하는 객체이다.
전체 시퀀스를 한번에 메모리에 정렬, 생성하는 것이 아니라 큰 시퀀스를 순회 할 수 있다.
보통 제네레이터는 이터레이터에 대한 데이터 소스로 이용되며, range도 제네레이터에 속한다,
제네레이터의 경우 순회할때 마지막 호출된 항목을 기억하고 다음 값은 반환,
이것의 함수와 차이는 이전 호출에 대한 메모리가 없으며, 항상 똑같은 상태로 진행된다.
메모리 관리에 매우 좋다.

간단한 제네레이터 예

 

우리만의 range함수를 만들면 다음과 같고 return은 yield이다.
yield는 제네레이터를 만드는 것 이며, 호출시 한번 return 그 뒤에 다시 다음 코드부터 실행된다.

yield로 인해 generator가 반환 된다. 출력은 이터레이터 처름 사용한다.
이러한 예를 확인하자, yield 1 , 2 , 3 함수를 호출 할때마다 next 1, next 2, next 3이 출력된다.
사용 될때마다 함수가 진행된다.

이정도 예를 들면 yield에 대해서 이해가 될 것이라고 생각된다.
제네레이터 객체를 순회 할 수 있다.
이때 순회를 마친 제네레이터는 출력이 없다.

마지막에는 출력이 안된다.

제네레이터도 컴프리헨션, generator comprehension이 가능하다.
앞에서도 좀 알아봤지만 ()를 이용한  것이다.
한번 홀수 , 짝수 가지는 generator를 만들어보자.

제네레이터는 메모리관리에 좋으니 자주 사용하도록하자.

데커레이터는 하나의 함수를 취해서 다른 함수를 반환하는 함수이다.
코드를 바꾸지 않고 함수를 수정하는것.

이를 알기 위해서는 *args **kwargs, 내부함수, 함수 인수를 알아야한다.

다음과 같은 함수가 있다하자.

한번 두 숫자를 곱하는 함수도 만들어보자.

아주 간단한 것

document에는 어떻게 전달할까? 

이렇게 전달 하는 방법도 있다.

하지만 이렇게 하는 방법이 더 좋을거같다 . 파이썬은 저자의 말대로 뭐든 간단하면 좋다!

더 깔끔한가? 아직 파이썬을 잘 모르는 나에겐 어렵다


데커레이터는 좀 어려우니 다시 정리하기로 한다.

 

 


지역변수, 전역변수 언제나 어렵다.
모든 언어에서 중요하기도 하다.
아무것도 전해주지 않앗는데 name을 전역변수로 보고 출력한다.

print_name에 아무것도 전해 주지 않아도 전역변수를 name을 출력

name을 변경이 가능할까?

이렇게 전역변수를 함수 안에서 변경할려 하면 error가 발생한다.

아래의 경우는 다른 경우이다.
전역변수 김현우로 인해 김현우가 출력,아래는 change_name함수의 지역변수 name으로 인해 오태승이 출력.
그러므로 print_name을 다시 호출하면 오태승이 아니라 김현우가 나온다.

잘 참고하자.

지역변수는 함수가 끝나면 사라진다.

local()과 globals()을 한번 사용 해보자. 이것들은 딕셔너리 형태로 반환한다.

지역변수에는 오준수 윤우재, 전역변수는 다양한 전역변수가 들어있으며 name은 김현우, name2는 조현호가 들어가 있다.

그러면 global을 어떻게 함수 내에서 변경 하냐. 파이썬의 경우 명시해주면 된다.

전역변수 name들이 함수안에서 바뀐다.

이름에 _와 __ 사용하는 것은 파이썬 내부 사용하므로 예약 되어있다.
이러한 걸 쓸 확률이 낮으니 개발자들이 _를 선택한것이다.
뭐 너무 많지만 간단한 사용을 다음과 같다.

함수의 이름 __name__, 설명 __doc__

그리고 메인 프로그램에는 특별히 __main__을 사용 하는 것 들이 있다.

 

이러한 함수를 이용하여 재귀 함수를 만들 수 있다.
재귀함수는 자기 자신을 재참조 하는것 항상 termination condition이 필요하다.아니면 무한루프에 빠진다.

종료조건이 없는 경우 다음과 같이 무한루프에 빠져서 멈춘다.

파이썬에서는 이허한 재귀함수의 깊이를 정할 수 있다. 참고로만 알아두자

재귀 함수로는 브루트포스 아니면 몇차원 데이터를 펴는데 사용 할 수 있다.
다음 예를 확인하자.

많은 차원을 가진 데이터를 펴주었다.


예외처리는 필수일것이다.

프로그램이 예외가 발생하는 경우마다 멈추게 하기 싫다면.
모두 try: except:로 처리한다. 다음 예를 확인하자.

다음과 같은 경우 zeroDivisionError가 발생한다. 그러므로 프로그램이 멈춘다,
except 처리로 0/100은 출력 100/0은 error가 출력

한마디로 try문에 error가 있으면 프로그램을 멈추는 것이 아니라 except로 전달한다.
위의 예제의 경우 except에 따로 정의된 error가 없으므로 모든 error을 받는다.

다음과 같이 해보자.
except 예외 타입 as 이름
이렇게 하면 error내용을 as 뒤에 이름에 저장한다.

이상한 인덱스 초과해서 전달시 out of range, 문자열은 invalid literal

위의 코드는 indexerror만 따로 처리하며 나머지 error는 모두 exception에서 처리한다.
그러면 이러한 예외를 만들 수 있을까?
그렇다 class를 이용하면 만든다. 뭐 다음장이 클래스라 다음에 해도 상관없지만 간단한 예를 들면 이렇다.

다음을 보면 숫자가 나오면 error가 나오도록 Numbererror를 만들었다.

parameter로는 Exception, 에러 발생은 raise로 한다.
숫자가 나오면 error
이것도 try except로 받아보자

우리가 만든 예외가 받아지는 것을 알 수 있다.

 

연습문제 솔루션은 깃허브에 올린다.
https://github.com/kimhyeonwokk/introducing_python_solution

 

GitHub - kimhyeonwokk/introducing_python_solution: Practice Solution in Introducing Python Books

Practice Solution in Introducing Python Books. Contribute to kimhyeonwokk/introducing_python_solution development by creating an account on GitHub.

github.com

 

이번에는 Chapter 6 부터 Chapter 8 까지 스터디를 진행 하였다.
http://www.yes24.com/Product/Goods/29289816

 

처음 시작하는 파이썬 - YES24

파이썬으로 프로그래밍에 입문하자!데이터 분석, 금융, 자연 과학 등 다양한 분야에서 각광받는 언어 파이썬. 개발자가 아니더라도 개발자가 되고 싶다면, 개발자지만 파이썬을 처음 시작한다

www.yes24.com

책의 구매 링크이다.
저번 주차 스터티 보고서링크는 다음과 같다.
https://inha-kim.tistory.com/33

 

[처음 시작하는 파이썬] 1주차 스터디 정리 [파이(py) 맛보기],[ 데이터: 타입, 값, 변수, 이름],[숫

WEBS 동아리 스터디로 다음과 같이 처음 시작하는 파이썬으로 제대로된 파이썬 공부를 시작 하였다. http://www.yes24.com/Product/Goods/29289816 처음 시작하는 파이썬 - YES24 파이썬으로 프로그래밍에 입문

inha-kim.tistory.com

[chapter 6] 반복문: while과  for문


코드를 한번 이상 실행 하는 것은 while과 for문이 필요하다.
아주 간단한 while문은 다음과 같다.

간단한 while문 이다.

count가 1 이였다가, print 한 뒤에 +1이 되는 것을 알 수 있다.
while문은 반복적인 조건문 이므로 count가 11이 되는 순간 멈추게 된다.


저러한 조건 말고, 무한루프중에 멈추는 방법은 break가 있다.

다음과 같이 가능하다.

이 프로그램은 q를 입력하면 종료하게 되며, 아니면 모두 대문자로 변환 된 것이 출력된다.

continue는 break와 반대 같지만, 이것은 반복문을 중단 하지 않고, 아래의 코드를 모두 뛰어넘는 것이다.
다음과 같이 사용이 가능하다.

예제

c로 시작하는 단어가 입력시에는 continue이 되는 것을 알 수 있다.

continue 아래 코드는 모두 무시, while문이 다시 시작된다.


break문이 어떤것을 확인 하면 종료 하지만, 모두 체크하고도 break가 되지 않을 경우 다음과 같이 else: 를 통해서 출력이 가능하다.

다음과 같이 else를 이용하면 while 문이 break에 안걸리면 출력된다.

 

파이썬의 이터레이터는 매우 유용하게 사용된다.
자료구조가 엄청 커도 , 어떻게 구현되든 무조건 자료구조를 순회하게 해준다.
for과 in을 사용하면 된다.

오른쪽이 더 파이썬 같은 방식이다. 간결하고, 보기좋다.

break와 continue은 동일하게 작동한다. 

thxxu 에서 u는 break, x는 continue한다.

else: 를 이용하면 break가 호출이 되지 않으면 else안에 있는 것들이 실행된다.

u가 없으므로 다음과 같이 호출된다.

 

숫자 시퀀스를 생성하는 range는 다음과 같이 사용하다.

range(start,end,steps), start는 생략시 0부터, stop은 항상 입력하며 stop-1 까지, step는 생략시 1, 아닐시에는 설정이가능하다. return 은 반복이 가능한 이터레이터 이다.

 0 ~ 9 까지 출력된다. 그 다음은 0,10, steps 2이므로 0,2,4,6,8 이 출력 된다.
start 2, end -1, steps이 -1 이므로 2 1 0 이 된다.

return을 range 인 것을 알 수 있다.
list 로도 만들 수 있다.

list를 만들기도 쉬워진다.

[chapter 7] 튜플과 리스트

 

python에는 두가지 다른 시퀀스 구조가 있다.

하나는 튜플 하나는 리스트, 튜플은 불변 이며, 리스트는 가변이다.

튜플 생성에는 다양한 방법이 있다.

빈 튜플은 다음과 같이 생성한다.
다음과 같은 방법들이 있으며,  ","를 있지 말자. 안쓰면 string

요소가 두개 이상 이면 마지막에 , 는 써도 상관 없고, 안써도 상관없다. 매우 관대한 언어이다.

모두 튜플이다.

다음을 보고 잘 알아두자. type이 했갈릴때가 있을 수도 있다.

두번째는 string이다

tuple은 여러 변수에 한번에 할당이 가능하다.
이것을 튜플 언팩킹(tuple unpacking)이라고 부르며, 다음과 같은 예제들이 있다.

다음과 같이 사용이 가능하다,두 변수를 교체할때도 유용하게 쓰인다.

 

tuple()을 사용하면 튜플을 만들 수 있으며, + 로 튜플을 결합 할 수 있다.

다음과 같은 예제가 가능하다.

*는 복제하는 것이다.

복제하여 원소가 3개가 되었으며, 클래스는 tuple이다.

순회는 다른 이터레이터 똑같이 작동한다.

간단하게 작동 하는 것을 알 수 있다.

튜플은 불변객체이므로 수정이 불가능하다.
수정하는 것 처럼 보이지는 주소가 바뀌는 것 을 알 수 있다.

tuple1 += tuple2는 주소가 바뀐다.

 

리스트는 데이터를 순차적으로 파악하는데 유용하며, 문자열과 달리 리스트는 변경이 가능하다.
현재 위치에 추가, 삭제하거나 기존 요소를 덮어쓰기, 등이 가능하며, 여러값이 여러번나오기도 가능하다.

리스트를 생성하는 법은 []이다. 이다. 생성하는 것은 list()함수를 이용한다.

다양한 방식으로 list가 사용이 가능하다. 

list 생성은 다음과 같이 가능하다.

list함수 이며, 문자열, 튜플 등 다양한 것에서 가능하다

split 메서드는 앞에서 문자열을 split하는 것이다.
string 에다가 사용하면 list가 나오는 것을 알 수 있다.

다음과 같이 다양한 방식으로 리스트를 만들 수 있다. 

offset으로 string과 동일하게 특정 값을 추출 할 수 있다.

하는 방식은 다음과 string과 동일하다.

0은 0, 10은 10, -1은 10, -10은 1 인것을 알 수 있다.

리스트 또한 슬라이스로 얻을 수 있다.

스트링과 동일하게 [start:end:step] 형식이다.

다음과 같이 숫자를 출력 할 수 있다.

동일하게 이 경우 error는 발생 하지 않는다.

에러는 생기지 않는다. 단지 scan 일 뿐이다.

리스트를 반대로 뒤집는 것은 reverse 메서드 이다. 이 메서드는 리턴이 없다.

첫 출력은 None 그 다음은 숫자이다.

리스트 맨 끝에 항목을 더하는 것은 append를 사용한다.
insert는 index, 값을 전달 받으면 그 위치에 삽입한다.리스트 끝을 넘는 인덱스를 주면 자동으로 맨 뒤에 더한다.

너무 편한언어^^

6을 넣고 , 3번째 인덱스에 3을, 1000번째에 7을 넣는다.

*를 이용하여 항목을 복제 할 수 있다.

[1] 이 3개로 복사된다.

리스트의 병합은 extend()와 + 또는 +=이용하면 된다.

append는 리스트 자체가 그 앞에 리스트의 원소로 들어간다. 예를 확인하자.

extend로 확장 한 것이다.
+= 로 더한 것이다.
append로 하면 A_class의 마지막에 B_class가 통째로 삽입된다.

offset으로 리스트의 값을 바꿀 수 있다, 또한 슬라이스를 이용하여 바꿀 수도 있다.
슬라이스 항목수와 달라도, 아무것도 없어도 상관없다.

다음과 같이 변경이 가능하다.

심지어 list가 아니라 튜플이 와도 상관없다.
심지어 문자열까지 된다.

파이썬이 매우매우 자비로운 언어인 것을 알 수 있다.

오프셋으로 항목을 삭제하는 것은 del 을 이용하면 된다.
삭제 된 곳 뒤가 앞당겨져서 온다.

삭제의 예 이다.

값으로 항목을 삭제 하는 것은  remove() 메서드를 사용하면 된다.

이것은 같은 값이 중복 되면 맨 앞에 있는 것을 삭제한다.

remove로 맨 처음 1이 삭제가 되는 것을 알 수 있다.

offset은 pop으로 항목을 삭제하며, return값으로 그 값을 가져온다.
pop()에 아무것도 안넘기면 -1, 맨 뒤이며, 값을 주면 offset값을 지운다.

number에서 pop하면 맨뒤, pop(2)는 두번째

파이썬 3.3이상에서는 모든 항목을 지우는 clear() 메서드가 새로 생겼다.

모두 지워지는 것을 알 수 있다.

값으로 인덱스를 찾을 수도 있다.

이때 나오는 인덱스는 제일 먼저 나온 것 이다.

제일 먼저 나오는 것의 인덱스를 출력

존재 여부 확인은 in을 사용한다,
return 은 true or false 이다.

다음과 같이 존재 여부를 in으로 확인가능하다.

값을 세는 것은 count()를 이용한다.

3, 0 이 return 된다.

join은 문자열로 변환하는 것이다.
이걸로 form이 있는 문자열로 합칠 수 있다.

이터레이터 들이 join 사용 가능하다

정렬하는 sort와 sorted가 있다.
두개의 차이는 sort는 리스트 자체를 내부적으로 sort하지만,
sorted는 복사본을 return 한다.

sort는 메서드로 return 이 없다, 내부적으로 sort, sorted는 함수로 원본 list는 영향이 없다.

항목의 개수를 얻는 것은 len 함수이다.
다른 타입에도 사용이 가능하다.

원소의 개수 9 return

= 할당하기는 가변성질을 가지고 있는 list이므로 주의 해야한다.
다음과 같은 예제를 확인하자.

b = a 이렇게 하여도, 메모리 주소가 같아 하나만 바꿔도 값이 바뀌는 것을 알 수 있다.

그러면 어떻게 복사할까.

세가지 방법이 있다.

copy 메서드, list 변환 함수, 슬라이스 [:] 등을 사용 하는 것이다.

다음과 같이 하면 복사가 가능하다. id가 다른 것을 알 수 있다.

깊은복사 deepcopy()
리스트의 값이 모두 불변이면 copy() 가 잘 작동한다.
하지만 하나라도 가변이 있으면 원하는대로 작동이 안할 수 있다.
이 예를 확인해보자.

복사가 잘 된것처럼 보인다.

복사가 잘 된것 같지만 아니다.
리스트 안에 불변 객체는 문제가 안된다 하지만 리스트 안에 리스트 즉 가변객체가 있으면 다음과 같은

의도하지 못한 상황이 발생한다.

이런 상황이 발생한다.

위에 있는 것들은 얕은 복사 이기 때문이다. deepcopy를 사용하자.
이를 사용 하는 방법은 copy 를 import 해주자.

deepcopy는 중첩된 리스트, 딕셔너리, 기타 다른 객체들은 모두 복사한다.

정상적으로 복사가 되는 것을 알 수 있다.

리스트는 비교가 가능하다. 

이는 매우 유용하다.

같은 offset의 항목을 비교한다.

다음과 같이 비교 연산을 사용 가능

for 과 in을 사용 할 수 있다.

break가 호출이 안되면 thank u, break가 되면 else가 출력 안된다.

list에 아무 것도 없으면 else가 실행된다.

바로 thank u 가 실행

여러 시퀀스를 순회하는 것은 zip을 이용 하면 된다.

시퀀스의 길이가 다르면 다음과 같이 제일 짧은게 끝나면 멈춘다.

간단한 zip 사용법

 다음과 같이 list로 만들 수 있다.

리스트 안에 튜플이 있는 형식 이다.

dict()로 딕셔너리도 만들 수 있다.

다음 장에 자세한 내용을 배운다.

list comprehension, 리스트 컴프리헨션은 한줄로 리스트를 만들 수 있다.
잘만쓰면 매우 편하다.
파이써닉한 방식이다. [ 표현식 for 항목 in 순회 가능한 객체 ]
다양한 예를 참고하자.

이렇게 간단하게 숫자를 넣을 수 있다.

이러한 방식도 있다.

다음과 같은 방식도 가능하다.

여기다가 조건을 줄수도 있다.
[ 표현식 for 항목 in 순회 가능한 객체 if 조건]
홀수, 짝수 예를 들어보자.

다양한 곳에서 활용이 가능하다.

다음과 같은 경우도 가능하다.
for in 을 두번 쓰는 것이다.
for in ( for in) 이런 구조라고 생각하면 편하다.

이중포문을 생각하면 편하다.

튜플 언팩킹으로 다음과 같이도 가능하다.

튜플 언팩킹

리스트안에 리스트도 넣을 수 있다.

다음 예를 보자.

오프셋으로 출력을 해보면 다음과 같다.

리스트 안에 리스트가 있다. 

리스트와 튜플의 차이는 뭘까?

튜플은 리스트의 append(), insert()가 없다. 그러면 튜플이 있는 이유는?

- 튜플은 더 적은 공간을 사용

- 실수로 튜플의 항목이 손상될 염려가 있다.

- 튜플은 딕셔너리 키로 사용 가능

- 네임드튜플(10.11) 객체의 단순 대안이 된다.

 

가변타입은 컴프리헨션이 있지만, 튜플은 없다.

작동은 가능하지만 이것은 제네레이터 컴프리센션이다. 제네레이터 객체를 반환한다.

9.8절에 배운다.

 

[chapter 8] 딕셔너리와 셋

딕셔너리는 리스트와 비슷하지만, 순서를 따지지 않는다.

그러므로 0또는 1과 같은 offset 으로 항목을 선택 할 수 없다.

대신 고유한 key와 value를 사용한다.
배열이나 리스트와 다르게 딕셔너리는 매우 좋다,

 

딕셔너리는 {} 와 dict()를 이용 하여 만들 수 있다.

다음과 같은 예제를 확인하자.

정상적으로 딕셔너리가 생성 된 것을 알 수 있다.
dict로 다음과 같이 딕셔너리로 만들 수 있다.

이렇게 예약어, keyword를 사용하면 error가 발생한다.

keyword는 쓰지 못한다.

또한 dict는 변환이 가능하다.

물론 두 값으로 이뤄지는 시퀀스만 가능하다.

리스트를 dict로 변환.
list 안에 tuple 형태도 가능하다.
튜플안에 리스트도 가능하다.
튜플안에 튜플도 가능핟,

다음과 같은 형태도 가능하다 매우 관대한 파이썬..

리스트와 튜플이 다음과 같이 가능하다.

 

항목을 추가 및 변경은 다음과 같이 한다.

[key]를 사용한다. 다음과 같은 예제를 확인하다.

다음과 같은 것을 딕셔너리가 존재한다.

여기서 value 변경은 다음과 같이 한다.

다음과 같이 value를 바꿀 수 있다.

새로운 것은 어떻게 추가하나? 다음과 같이 하면 된다.

딕셔너리에 없는 것을 추가한다.

여기서 만약 키 값이 동일하면 마지막에 들어 온 것으로 대체된다.

키값은 항상 고유해야한다.

기존에 있던 'one' : 10 이 대체 된 것을 알 수 있다.


딕셔너리에서 항목을 얻는 것은 [key] 아니면 get()을 이용한다.

[key]는 없으면 error가 발생한다.

이 경우 key에 해당하는 값이 dict에 있다.
이 경우 error 가 발생한다.

이러한 것을 방지 하기 위해 get를 이용하면 된다.

다음과 같이 있는 것을 하면 value가, 아닐 시에는 None이 출력 된다.

이때 옵션 값을 주어, none이 출력이 아니라 다음과 같이도 가능하다.

없으므로 not found가 출력 된다.

모든 key를 얻는 것은 keys()를 사용하면 된다.
모든 value를 얻는 것은 values()를 쓰면 된다.
list와 같이 쓰면 반복가능한 이터레이터로 만들 수 있다.

keys와 values 사용법이다.

 

여기서 모든 key와 value를 얻는 것은 items를 사용한다.
len은 키-값 쌍의 개수를 가져온다.

모두 가져오며, 키와 값은 튜플형태이다. 길이는 4 이다.

결합하기는 다음과 같이 가능하다.

파이썬 3.5 이상부터 **를 지원한다.

하지만 이건 얕은 복사이다. 세개이상도 지원한다 , 그냥 뒤에 추가로 써주면 된다.

다음과 같이 결합이 가능하다.

결합하기는 update()로도 가능하다.
이것은 한 딕셔너리의 키와 값을 복사하여 다른 것에 붙이는 것 이다.
같은 key 가 있으면 마지막에 들어온 key값으로 대체된다.

업데이트로 더해지는 것을 알 수 있으며 'one'의 key가 겹치므로 value가 10으로 바뀐다.

키와 del로 항목 삭제가 가능하다.

없는 것을 지우면 error가 뜬다.

키로 항목 가져온 뒤에 제삭제하는 것은 pop이다

이 또한 없는 것을 지우면 error가 발생한다.

모든 항목을 삭제 하는 방법은 clear()를 사용한다.

다음과 같이 작동한다.

딕셔너리에서도 in 이 가능하다.
이것은 key 값을 체크한다.

다음과 같이 true false를 체크가 가능하다.

할당하기는 = 는 리스트와 마찬가지로 참조하는 것 이므로, = 로 할 시에 하나가 변경시 모두가 변경된다.

다음과 같이 모두 변경된다.

copy를 사용하면 어느정도 문제를 해결 할 수 있다.

어느정도 해결이 가능하다.

하지만 위에서 설명 한 것처럼 list같은 가변 객체가 들어가 있으면 다음과 같은 문제가 발생한다.

number1만 변경 하는데 모두 변경된다.

이럴때는 deepcopy를 사용한다. 위에서도 했다.

import copy

문제가 해결 된 것을 알 수 있었다.

딕셔너리 비교는 == != 만 가능하다.

딕셔너리는 순서를 별로 중요하지않게 생각하는 것을 잊지말자.

순서는 중요하지 않다.

순회는 for과 in으로 한다.
다음과 같은 것으로 key value item을 출력 할 수 있다.

간단하게 할 수 있다.

 

딕셔너리도 컴프리헨션이 가능하다.
많이 본 형태이다 {키_표현식: 값_표현식 for 표현식 in 순회가능한 객체}

letter이 key, count가 value이다.
set로 하면 더욱더 보기 좋다.

다중 for문도 가능하며, if도 가능하다.

{키_표현식: 값_표현식 for 표현식 in 순회가능한 객체 if test}

다음과 같이 가능하다.

셋은 간단하게 생각하면 키만 남은 딕셔너리라고 생각하면된다.
집합, 정규교욱과정만 배웠으면 모두 아는 내용 이다.

 

set()은 생성과 변환이 가능하다.
{ } 과 set이라는 것 이다.

set사용법

empty_set의 출력은 set()이다.
그 이유는 {}는 딕셔너리이기 때문이다.

string list tuple set

중복은 제거한다. 집합의 성질이기 때문이다. 순서또한 중요 하지 않다.

그리고 딕셔너리의 경우 key값만 취하는 것을 알 수 있다.

여기서도 동일하게 len으로 길이를 구할 수 있다.

len으로 길이를 구할 수 있다.

항목을 추가 하는 것은 add()를 활용한다, 삭제는 remove이다.

add로 5가 들어오고, 삭제로 1이 나간다.

for과 in으로 순회, 멤버십 테스트로 in을 사용 할 수 있다.

for과 in으로 순회하여 숫자를 출력, in으로 존재여부를 확인가능

책의  나온 예제 중 하나이다.
딕셔너리 안에 key, value 로 set이 들어 간 형태이다.

술의 종류인가보다

여기서 vodka가 포함된 음료는?

다음과 같이 가능하다.

그러면 좀더 복잡한 예제로 보드카(vodka)가 섞인 음료 이며, cream과 vermouth를 안먹는 다고 한다.

뭐 다양한 방식으로 해도 상관없다,

셋은 집합이다. 집합에는 교집합 , 합집합 이런 것을 생각 할 수 있다.
그러면 위의 예제에서 셋 교집합 연산인 &를 사용해보자.
나는 vermouth or orange juice가 들어간게 먹고싶다고 하면다음과 같이 하면 된다.
이것은 있으면 true이다. 없으면 false

다음과 같이 잘 동작한다.

왜그럴까 저거의 retrun값을 확인 해보자.

다음과 같이 교집합이 없으면 set() false이고 있으면 하나라도 들어있는 set이 나온다.

앞에서 했던것을 해보자, vodka는 있고, cream과 vermouth는 안먹는다고 생각 해보자.

다음과 같이 파이썬답게 할 수 있다.

이제 뭐 간단하게 알아보자. 교집합은 & 와 intersection이 있다.

다음과 같이 가능하다.

그러면 합집합은 뭘까 |와  union이다.

합집합이다.

그러면 차집합도 있을까? - 아니면 difference()를 사용하면 된다.

간단하다.

이외에도 ^ symmetric_difference 가 있다.
대칭차집합으로, 한 set에는 포함이지만 두개의 set에 포함되지 않는 항목을 구하는 것 이다.

대칭차집합

부분집합인지 체크 하는 것은 <= 연산이나 issubset을 쓰면 된다.

간단하게 가능하다.

자기자신은 자기의 부분집합이다 까먹지말자.

진부분집합, 두번째 셋이 a말고도 원소가 더 있어야한다.이것은 < 를 이용한다.

다음과 같이 체크가 가능하다.

상위집합은 부분집합의 반대이다.
>= 이나 issuperset을 사용하면 된다.
>는 진 상위집합이다.
예를보면 다음과 같다.

그냥 간단하게 괄호방향으로 판단하자.

 

set의 comprehension 컴프리헨션은 쉽다. list 딕셔너리와 동일하다.

{표현식 for 표현식 in 순회가능한 객체}

{표현식 for 표현식 in 순회가능한 객체 if 테스트}

간단한 예를 보자.

홀수 짝수 대표적인 예 이다.

불변하는 set 이름 그대로 frozenset을 이용하면 된다.

다음과 같다. 한번 넣어볼까?
넣을려면 error가 발생한다.

여기서 배운 자료구조는 [] 리스트, () 튜플, {} 딕셔너리와 셋이 있다.
셋을제외하고는 모두 [ ]를 이용하여 접근한다. 예를 보자.

다음과 같이 가능하다, list tuple은 인덱스, dict는 key로 접근
셋은 error가 발생한다.

자료구조는 다양하게 결합이 가능하다.
다음과 같이 list를 확인하자.

다음과 같이 가능하다.

이러한 자료구조 결합은 제한사항이 매우 많다.

타입이 문제이다.
예를들어 딕셔너리의 키는 불변하다. 이는 리스트 딕셔너리 셋은 키가 될 수 없다는 것이다.
하지만 튜플은 불변이므로 딕셔너리의 키가 가능하다.

뭐 다양한 경우가 가능하다.

 

연습문제 솔루션은 깃허브에 올린다.

https://github.com/kimhyeonwokk/introducing_python_solution

 

GitHub - kimhyeonwokk/introducing_python_solution: Practice Solution in Introducing Python Books

Practice Solution in Introducing Python Books. Contribute to kimhyeonwokk/introducing_python_solution development by creating an account on GitHub.

github.com

 

+ Recent posts