<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>aiffel-hj.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Thu, 06 Jan 2022 09:45:47 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. aiffel-hj.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/aiffel-hj" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[간단한 분류기 실습]]></title>
            <link>https://velog.io/@aiffel-hj/%EA%B0%84%EB%8B%A8%ED%95%9C-%EB%B6%84%EB%A5%98%EA%B8%B0-%EC%8B%A4%EC%8A%B5</link>
            <guid>https://velog.io/@aiffel-hj/%EA%B0%84%EB%8B%A8%ED%95%9C-%EB%B6%84%EB%A5%98%EA%B8%B0-%EC%8B%A4%EC%8A%B5</guid>
            <pubDate>Thu, 06 Jan 2022 09:45:47 GMT</pubDate>
            <description><![CDATA[<p>오늘 아이펠 EXPLORATION 노드로 싸이킷런 5가지 분류기를 사용해봤다</p>
<ul>
<li>DecisionTreeClassifier</li>
<li>RandomForestClassifier</li>
<li>svm</li>
<li>SGDClassifier</li>
<li>LogisticRegression</li>
</ul>
<p>간단한 딥러닝이라고 해도 수학공식을 꿰차고 머신러닝 지식이 빠삭해야만 실습이 가능할 것 같았는데, 전혀 그렇지 않았다</p>
<pre><code class="language-python">
from sklearn.linear_model import LogisticRegression

logistic_model = LogisticRegression(random_state=32, max_iter=2500)
logistic_model.fit(X_train, y_train)
y_pred = logistic_model.predict(X_test)

print(&quot;[Report]\n&quot;, classification_report(y_test, y_pred, zero_division=0))
print(&quot;[Confusion Matrix]\n&quot;, confusion_matrix(y_test, y_pred))</code></pre>
<p>물론 단순한 데이터들이고 간단한 분류기이지만 코드 몇줄이 전부였다
각 모델부만 변경을 해주면 각 알고리즘에 따라 학습하고 검증한다</p>
<p>왜 모두의딥러닝 이라고 하는지 새삼 와닿기 시작한다</p>
<p>하루 빨리 딥러닝이 만만해졌으면 좋겠다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[파이썬 추상클래스]]></title>
            <link>https://velog.io/@aiffel-hj/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%B6%94%EC%83%81%ED%81%B4%EB%9E%98%EC%8A%A4</link>
            <guid>https://velog.io/@aiffel-hj/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%B6%94%EC%83%81%ED%81%B4%EB%9E%98%EC%8A%A4</guid>
            <pubDate>Wed, 05 Jan 2022 07:32:10 GMT</pubDate>
            <description><![CDATA[<h2 id="추상클래스abstract-class">추상클래스(abstract class)</h2>
<blockquote>
<p>추상클래스는 메소드 구현을 강제합니다</p>
</blockquote>
<p>어떤 클래스를 구현할 때, 반드시 정의해야 하는 메소드들을 Abstract Class 에 정의하여서</p>
<p>동일한 모델링을 <strong>강제</strong>할 수 있다.</p>
<pre><code class="language-python">from abc import ABCMeta, abstractmethod  # abc 모듈을 임포트 해야한다

class AnimalAbstract(metaclass=ABCMeta):  # metaclass 지정
    @abstractmethod  # 함수에 @abstractmethod 데코레이터 달아주기
    def set_bark(self):
        pass  # 함수 내 액션은 정의하지 않음

    @abstractmethod
    def bark(self):
        pass

class Dog(AnimalAbstract):  # Dog는 Animal 추상클래스를 상속했다
    pass

dog = Dog()
&gt;&gt;&gt; TypeError: Can&#39;t instantiate abstract class Dog 
with abstract methods bark, set_bark

# 추상클래스에서 강제한 메소드를 Dog 에서 구현하지 않았다</code></pre>
<p>올바른 Dog 클래스를 정의하려면</p>
<pre><code class="language-python">class Dog(AnimalAbstract):  # Dog는 Animal 추상클래스를 상속했다
    def set_bark(self, sound):
        self.sound = sound

    def bark(self):
        print(f&quot;이 동물은 {self.sound} 하고 울어요&quot;)

dog = Dog()
dog.set_bark(&quot;멍멍&quot;)
dog.bark()  # 이 동물은 멍멍 하고 울어요</code></pre>
<p>혹은 이런방법도 가능하다</p>
<pre><code class="language-python">class Animal:
    def set_bark(self):
        raise Exception(&quot;set_bark를 구현하시오&quot;)

    def bark(self):
        raise Exception(&quot;bark를 구현하시오&quot;)

class Tiger(Animal):
    __sound = &quot;울음소리&quot;  # private
    def set_bark(self, sound):
        self.__sound = sound
    def bark():
        print(self.__sound)

class Cat(Animal):
    pass

tiger = Tiger()
tiger.set_bark(&quot;어흥&quot;)
tiger.bark()  # 어흥

# Cat 에서 필수 메소드 구현을 깜빡했다.
cat = Cat()
cat.set_bark(&quot;야옹&quot;)  # Exception: set_bark를 구현하시오
cat.bark()  # Exception: bark를 구현하시오</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[파이썬 클래스 상속]]></title>
            <link>https://velog.io/@aiffel-hj/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%ED%81%B4%EB%9E%98%EC%8A%A4-%EC%83%81%EC%86%8D</link>
            <guid>https://velog.io/@aiffel-hj/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%ED%81%B4%EB%9E%98%EC%8A%A4-%EC%83%81%EC%86%8D</guid>
            <pubDate>Tue, 04 Jan 2022 10:58:34 GMT</pubDate>
            <description><![CDATA[<h2 id="1-클래스의-상속">1. 클래스의 상속</h2>
<blockquote>
<p>클래스를 상속한다. 부모 클래스를 자식이 상속한다.
(부모 재산을 자식이 상속받는다) 부모는 자식의 상위개념</p>
</blockquote>
<p>코드로 상속은 이렇게 표현한다.</p>
<pre><code class="language-python">class Parent:
    pass

class Child(Parent):  # 자식이 부모를 상속받았다.
    pass</code></pre>
<h2 id="2-상속-활용하기">2. 상속 활용하기</h2>
<h3 id="상속여부-확인해보기">상속여부 확인해보기</h3>
<p>정말 상속이 되는지 확인해보자</p>
<pre><code class="language-python">class Parent:
    finance = 500000000  # 5억

    def greeting(self):
        print(&quot;안녕하세요&quot;)

    def my_finance(self):
        print(f&quot;재산은 {self.finance}원 입니다&quot;)

class Child(Parent):
    pass

c = Child()
print(c.finance)  # 500000000
c.greeting()  # 안녕하세요
c.my_finance()  # 재산은 500000000원 입니다

# 상속여부 확인
issubclass(Child, Parent)  # True</code></pre>
<p>자식 클래스인 Child 에는 변수 finance, 함수 greeting(), my_finance()를 선언해주지 않았음에도 자식이 그대로 상속받아 사용할 수 있다.</p>
<p>생성자, 비공개 변수, 비공개 메소드, staticmethod, classmethod 상속여부 확인해보기</p>
<pre><code class="language-python">import datetime

class Human:
    name = &quot;김민국&quot;  # public var
    __born = &quot;한국&quot;  # Private var

    def __init__(self, name, born):
        print(&quot;Human.__init__&quot;)
        self.set_public_name(public_name)
        self.__set_born(born)

    def display_name(self):
        print(f&quot;제 이름은 {self.name}, 태어난 곳은 {self.__born} 입니다&quot;)

    def set_name(self, name):
        self.name = name
        print(f&quot;제 이름은 {self.name} 입니다&quot;)

    def __set_born(self, born):
        self.__born = born
        print(f&quot;전 {self.__born} 에서 태어났어요&quot;)

    @staticmethod
    def birth_to_age(year):
        return datetime.datetime.now().year - year

    @classmethod
    def korean_age(cls, year):
        return cls.birth_to_age(year) + 1
               # Human.birth_to_age(year) + 1

class Student(Human):
    def __init__(self, name):
        print(&quot;Student.__init__&quot;)
        self.set_name(name)

    def my_born(self):
        print(f&quot;제가 태어난 곳은 {self.__born} 입니다&quot;)

s = Student(&quot;홍길동&quot;)
&gt;&gt;&gt; Student.__init__  # Human.__init__ 은 호출되지 않았다

s.my_born()
&gt;&gt;&gt; AttributeError: &#39;Student&#39; object has no attribute &#39;_Student__born&#39;
# 자식이 부모의 private 변수에 직접 접근할 수 없다

s.display_name()
&gt;&gt;&gt; 제 이름은 홍길동, 태어난 곳은 한국 입니다
# 부모의 함수를 통해서만 부모의 private 에 접근이 가능하다

print(Student.birth_to_age(1999))
&gt;&gt;&gt; 23  # Student를 생성하지 않고도 함수를 사용한다. @staticmethod 상속됨

print(Student.korean_age(1999))
&gt;&gt;&gt; 24  # birth_to_age() 사용하고 +1 한다. @classmethod 상속됨</code></pre>
<h3 id="상속을-거부할-순-없을까">상속을 거부할 순 없을까?</h3>
<pre><code class="language-python">import random
class Parent:
    finance = 500000000  # 5억원

    def greeting(self):
        print(&quot;안녕하세요&quot;)

    def my_finance(self):
        print(f&quot;재산은 {self.finance}원 입니다&quot;)

class Child(Parent):
    finance = 0  # 자식의 재산 재정의

    def greeting(self):  # 자식의 인사법 재정의(오버라이딩)
        greeting_msgs = [&quot;안녕&quot;, &quot;하이&quot;, &quot;ㅎㅇ&quot;, &quot;hi&quot;, &quot;왔냐&quot;, &quot;오랜만&quot;]
        random.shuffle(greeting_msgs)
        print(greeting_msgs[0])

c = Child()
print(c.finance)
c.greeting()  # 하이  // 부모는 안녕하세요
c.my_finance()  # 재산은 0원 입니다</code></pre>
<h3 id="자식이-부모를-부른다-super">자식이 부모를 부른다. super()</h3>
<pre><code class="language-python">class Parent:
    finance = 500000000

    def greeting(self):
        print(&quot;안녕하세요&quot;)

    def my_finance(self):
        print(f&quot;재산은 {self.finance}원 입니다&quot;)

class Child(Parent):
    finance = 0  # 자식의 재산 재정의

    def greeting(self):  # 자식의 인사법 재정의(오버라이딩)
        print(&quot;하이!&quot;)

    def my_parents_finance(self):
        print(f&quot;부모의 재산은 {super().finance}원 입니다.\n내 재산은 {self.finance}원 입니다&quot;)

c = Child()
c.my_parents_finance()

&gt;&gt;&gt; Output
부모의 재산은 500000000원 입니다.
내 재산은 0원 입니다

주의! 부모가 자식의 메소드를 사용할 순 없다.
p = Parent()
p.my_parents_finance()
&gt;&gt;&gt; AttributeError: &#39;Parent&#39; object has no attribute &#39;my_parents_finance&#39;</code></pre>
<blockquote>
<p>attribute: 클래스 내 메서드나 변수</p>
</blockquote>
<h3 id="실전-상속-활용하기list-클래스-확장">실전 상속 활용하기(list 클래스 확장)</h3>
<pre><code class="language-python">&quot;&quot;&quot;
리스트를 정말 많이 활용하는데..
원래 정의된 리스트는 손대지 않으면서 내가 원하는 부분만 손대보자(확장!)
&quot;&quot;&quot;
a = list()
# IDE 에서 Ctrl(Command) + 클릭 해보면 선언 되어있는 곳으로 이동할 수 있다.

# list가 정의되어있는 파일을 따라가보면..
class list(object):  # 클래스로 선언되어 있다
    ...  # 기본 메소드들 정의
    def append(self, *args, **kwargs):
        &quot;&quot;&quot; Append object to the end of the list. &quot;&quot;&quot;
        pass

# 확장 클래스 정의
class MyList(list):  # 리스트를 상속하는 MyList를 만든다
    def append(self, *args, **kwargs):
        # 특별한 경우가 아니라면 부모의 인자들은 모두 보존하자
        print(&quot;append가 호출됐어요&quot;)

my_list = MyList()  # my_list = list()
my_list.append(10)
print(my_list)  # []</code></pre>
<p>list 클래스를 상속받아 append() 메소드를 오버라이딩 했더니, 원래 정의된 .append()가 정의되지 않았다.</p>
<p>print() 문을 유지하면서도, 부모의 append() 기능을 그대로 사용하려면</p>
<pre><code class="language-python">class MyList(list):  # 리스트를 상속하는 MyList를 만든다
    def append(self, *args, **kwargs):
        super().append(*args, **kwargs)  # 부모의 .append()를 그대로 호출
        print(&quot;append가 호출됐어요&quot;)

my_list = MyList()
my_list.append(10)
print(my_list)
&gt;&gt;&gt; Output
append가 호출됐어요  # 자식이 출력한 구문
[10]  # 본래 기능이 보존됐다</code></pre>
<p>부모의 기능도 보존하고, 내 의도도 반영되었다.</p>
<p>그럼 이 append() 기능을 조금 변형시켜보자. append를 반복할 횟수를 지정해보면 어떨까?</p>
<pre><code class="language-python">class MyList(list):  # 리스트를 상속하는 MyList를 만든다
    def append(self, *args, **kwargs):
        if &quot;loop&quot; in kwargs:  # kwargs에 loop=n 형식으로 넘어왔다면
            loop = kwargs[&quot;loop&quot;]  # 할당하고
            del kwargs[&quot;loop&quot;]  # 지워줘야 한다. 본래 부모의 append는 loop를 사용하지 않는다.
            for i in range(loop):
                super().append(*args, **kwargs)
        else:
            super().append(*args, **kwargs)

my_list = MyList()
my_list.append(1)  # 1을 한번 넣고
my_list.append(5, loop=5)  # 5를 5번 넣을래
print(my_list)  # [1, 5, 5, 5, 5, 5]  # 1 한번, 5는 다섯번</code></pre>
<h3 id="상속의-순서-다중상속">상속의 순서, 다중상속</h3>
<p>클래스는 연쇄 상속이 가능하고, 한번에 여러 클래스를 상속할 수 있다.</p>
<pre><code class="language-python">class Human:
    pass

class Parent(Human):
    pass

class Child(Parent):
    pass

print(Child.mro())  # 해당 클래스가 어떤 순서로 호출되는지 확인할 수 있다.
&gt;&gt;&gt; [
  &lt;class &#39;__main__.Child&#39;&gt;, 
  &lt;class &#39;__main__.Parent&#39;&gt;,
  &lt;class &#39;__main__.Human&#39;&gt;,
  &lt;class &#39;object&#39;&gt;
]</code></pre>
<p>한번에 여러 클래스를 상속할 수 있다</p>
<pre><code class="language-python">class Human:
    pass

class JamMin:
    pass

# Parent와 JamMin 두개 클래스를 상속한다.
# 순서는 왼쪽(우선) -&gt; 오른쪽
class Child(Human, JamMin):
    pass

print(issubclass(Child, JamMin))  # True
print(issubclass(Child, Human))  # True

print(Child.mro())  # 해당 클래스가 어떤 순서로 호출되는지 확인할 수 있다.
&gt;&gt;&gt; [
  &lt;class &#39;__main__.Child&#39;&gt;,
  &lt;class &#39;__main__.Human&#39;&gt;,
  &lt;class &#39;__main__.JamMin&#39;&gt;,
  &lt;class &#39;object&#39;&gt;
]</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[클래스에서 @staticmethod와 @classmethod의 차이]]></title>
            <link>https://velog.io/@aiffel-hj/%ED%81%B4%EB%9E%98%EC%8A%A4%EC%97%90%EC%84%9C-staticmethod%EC%99%80-classmethod%EC%9D%98-%EC%B0%A8%EC%9D%B4</link>
            <guid>https://velog.io/@aiffel-hj/%ED%81%B4%EB%9E%98%EC%8A%A4%EC%97%90%EC%84%9C-staticmethod%EC%99%80-classmethod%EC%9D%98-%EC%B0%A8%EC%9D%B4</guid>
            <pubDate>Mon, 03 Jan 2022 09:19:50 GMT</pubDate>
            <description><![CDATA[<p>클래스를 배우다보면 두가지 추가개념이 등장한다.
@staticmethod와 @classmethod</p>
<p>이 두가지 개념은 추상적으로 아래와 같이 구분할 수 있다.</p>
<p>@staticmethod: 클래스 내에서 구현하지만 클래스에 접근하지 않고 독립적인 행위를 하는
@classmethod: 클래스를 생성하지 않고도 클래스에 접근하여 무언갈 하는</p>
<p>코드로 확인해보면</p>
<pre><code class="language-python">class TextManager:
    @staticmethod
    def is_korean(txt):  # 클래스 내부로의 접근이 없다
        &quot;txt가 한국어 인가요?&quot;
        match = re.search(r&quot;[ㄱ-ㅎ|ㅏ-ㅣ|가-힣]&quot;, txt or &quot;&quot;)
        return match is not None

    @classmethod
    def language_classification(cls, txt):  # 클래스 내부의 is_korean 을 쓴다
        &quot;언어 판별&quot;
        return &quot;korean&quot; if cls.is_korean(txt) else &quot;others&quot;</code></pre>
<p>@staticmethod는 cls 인자를 받지 않지만
@classmethod는 cls 인자를 받는다.
이 cls는 클래스 자신을 의미한다.</p>
<p>외부에서 is_korean(&quot;한국어&quot;) 함수를 사용하고 싶다면 @staticmethod로 선언한다.
TextManager를 만들면서 한글을 판별하는 메소드를 만들었으니, 다른 곳에서 재작성 할 필요 없이 바로 가져다 쓸 때!</p>
<pre><code class="language-python">chk_korean = TextManager.is_korean(&quot;안녕하세요&quot;)
print(chk_korean)  # True</code></pre>
<p>마찬가지로 외부에서 language_classification(&quot;텍스트&quot;) 함수를 사용하고 싶다면 @classmethod로 선언한다. 단, 이는 클래스 내부의 변수나 함수에 접근해야할 때 사용한다</p>
<pre><code class="language-python">language = TextManager.language_classification(&quot;Hello&quot;)
print(language)  # others</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[람다 표현식]]></title>
            <link>https://velog.io/@aiffel-hj/%EB%9E%8C%EB%8B%A4-%ED%91%9C%ED%98%84%EC%8B%9D</link>
            <guid>https://velog.io/@aiffel-hj/%EB%9E%8C%EB%8B%A4-%ED%91%9C%ED%98%84%EC%8B%9D</guid>
            <pubDate>Fri, 31 Dec 2021 09:11:24 GMT</pubDate>
            <description><![CDATA[<h2 id="람다-표현식으로-만들기">람다 표현식으로 만들기</h2>
<blockquote>
<p>lambda ~~ 하는 구문을 많이 봤을텐데, 이를 람다식이라고 한다.
람다는 ‘익명함수’ 라고 불리는데, 말 그대로 이름이 없는 함수이다.</p>
</blockquote>
<p>코드로 확인해보면</p>
<pre><code class="language-python"># 일반적인 함수 방식
def add_10(x):  # 함수의 &#39;이름&#39;이 있다.
    return x + 10

# 위 add_10 함수를 람다로 표현하면
lambda x: x + 10</code></pre>
<p>도식화 시켜보면 생각보다 단순하다.</p>
<p><img src="https://images.velog.io/images/aiffel-hj/post/f3888e8f-a912-4a90-b85e-1ea790bb80da/Untitled.png" alt=""></p>
<pre><code>출처: 파이썬 코딩 도장(https://dojang.io/mod/page/view.php?id=2359)</code></pre><ol>
<li>lambda x: x+10<ol>
<li>x는 함수가 넘겨받을 <strong><em>인수</em></strong>이다. 예제는 단항만 넘겨받지만, 복수 개로 설정해도 상관없다.
lambda x, y, z: x+y+z</li>
<li>함수에서 사용하는 인자의 기본값은 설정할 수 있다.</li>
</ol>
</li>
</ol>
<pre><code class="language-python">        def add_10(x, y=10, z=20):
            return x + y + z

        lambda x, y=10, z=20: x + y + z</code></pre>
<ol>
<li>lambda x: x + 10<ol>
<li>x + 10은 리턴할 값이다.</li>
<li>함수에서 처럼 return 으로 명시하지 않는다.</li>
<li>넘겨받은 인자를 다 쓰지 않아도 상관없다.(꼭 다 써야하는 건 아님!)</li>
</ol>
</li>
</ol>
<pre><code class="language-python">        lambda x, y, z: x * z</code></pre>
<ol>
<li>람다 실행하기</li>
</ol>
<pre><code class="language-python">    # print 하면 람다함수임을 알려준다
    print(lambda x: x+1)  # &lt;function &lt;lambda&gt; at 0x7fdf9e346670&gt;

    # 그럼 바로 호출은?
    print( (lambda x: x + 1)(10) )  # 11

    # 변수에 익명함수 할당
    add_1 = lambda x: x + 1
    print( add_1(15) )  # 16</code></pre>
<h2 id="그래서-언제-쓰는데">그래서 언제 쓰는데?</h2>
<blockquote>
<p>lambda 함수는 보통 map, filter, reduce 함수와 함께 병행하여 사용된다.
이 3개 함수들은 인자에 함수를 넘겨받는데, 이를 일반 함수로 선언하지 않고 간단하게 끝내기 위해서!</p>
</blockquote>
<ol>
<li>map( ) 과 함께 사용</li>
</ol>
<pre><code class="language-python">    # 파이썬 내장함수를 써서 단순치환!
    list(map(int, &quot;123456&quot;))  # [1, 2, 3, 4, 5, 6]
    #  [ int(1), int(2), int(3) ... int(6)]

    # 넘겨받은거에 1씩 더해서 저장하고 싶은데..?
    # Case 1) int 를 그냥 넣을 수 있었으니까, 여기에 연산을 하면 되나?
    list(map(int(x)+1, &quot;123456&quot;))  # NameError: name &#39;x&#39; is not defined
    # int(x) 를 인식할 수 없다.

    # Case 2) 그럼 함수를 선언해서 사용하면 되겠네
    def add_1(x):
        return int(x) + 1

    list(map(add_1, &quot;123456&quot;))  # [2, 3, 4, 5, 6, 7]
    # 처음 1, 2, 3 ... 6을 1씩 잘 더해줬다.

    # Case 3) 고작 1만 더하려고 했는데 함수까지 선언해야돼? map에다 선언해야지?
    list(map(def add_1(x): return int(x)+1, &quot;123456&quot;))
    # SyntaxError: invalid syntax 발생..!!
    # map에서 함수를 받지만, 그렇다고 def로 함수를 선언할 순 없다.

    # Case 4) 그럼 간단하겐 못하나?
    list(map(lambda x: int(x)+1, &quot;123456&quot;))  # [2, 3, 4, 5, 6, 7]
    # 함수를 def로 선언하지 않아도 되네?

    # 물론 이렇게도 가능!
    add_1 = lambda x: int(x) + 1
    list(map(add_1, &quot;123456&quot;))</code></pre>
<ol>
<li>filter( ) 와 함께 사용</li>
</ol>
<pre><code class="language-python">    &quot;&quot;&quot;
    filter() 는 조건에 맞는 값만 골라서 되돌려 준다.
    0~10 사이 수 중 짝수만 리스트로 넣기
    &quot;&quot;&quot;

    # 리스트 표현식으로 필터링
    even_numbers = [i for i in range(10) if i % 2 == 0]  # [0, 2, 4, 6, 8]

    # filter()를 써보자
    # Case 1) 당연히 함수를 선언해서 써도 된다
    def is_even(x):
        if x % 2 == 0:
            return True
        return False

    even_numbers = list(filter(is_even, range(10)))  # [0, 2, 4, 6, 8]</code></pre>
<p>여기서 잠깐, 알고 가면 좋을 내용..</p>
<p><strong><em>if else 한줄로 표현하기</em></strong></p>
<pre><code class="language-python"># 홀짝을 판별하는 함수가 있다고 가정하면
y = 3
def odd_even(x):
    if x % 2 == 0:
        return &quot;짝수&quot;
    else:
        return &quot;홀수&quot;

odd_even(y)  # &quot;홀수&quot;

# 이런 단순 if-else 구조를 한줄에 표현하면
def odd_even(x):
    return &quot;짝수&quot; if x % 2 == 0 else &quot;홀수&quot;
# 함수여서 return 으로 값을 돌려줬다</code></pre>
<p><img src="https://images.velog.io/images/aiffel-hj/post/24b24523-afb3-40cb-8f88-a1eb0ba222c1/Untitled%201.png" alt=""></p>
<p>다시 코드로 돌아가서</p>
<pre><code class="language-python">def is_even(x):
    return True if x % 2 == 0 else False
    # 사실 단순 True / False 라면 if 문도 필요가 없다
    # return x % 2 == 0

even_numbers = list(filter(is_even, range(10)))  # [0, 2, 4, 6, 8]

# Case 2) 람다를 활용해보자
even_numbers = list(filter(lambda x: True if x % 2 == 0 else False, range(10)))

# 사실 여기선 if else 가 없이 비교 연산만으로 가능하잖아? 홀수를 뽑으면
odd_numbers = list(filter(lambda x: x % 2 != 0, range(10)))  # [1, 3, 5, 7, 9]
# 제일 깔끔!!</code></pre>
<ol>
<li><p>reduce( ) 와 함께 사용</p>
<p> 값을 누적시킬 때 reduce() 를 사용한다.
 reduce는 기본 내장함수가 아니라 functools 모듈에서 제공한다.</p>
</li>
</ol>
<pre><code class="language-python">    # 두 값을 더하는 함수를 만들어 보자
    def my_sum(x, y):
        return x + y

    # 일반적으로 구현하면
    total_sum = 0  # 누적 할 변수를 선언하고
    for i in range(1, 6):
        total_sum += i  # 반복문으로 누적시켜야 한다
    print(total_sum)  # 15
    # 코드가 좀 긴.. 듯 한데

    # reduce로 표현해보자
    from functools import reduce

    reduce(my_sum, range(1, 6))  # 15</code></pre>
<p><img src="https://images.velog.io/images/aiffel-hj/post/383035f7-afa3-4bf6-a734-e4262e3d550e/Untitled%202.png" alt=""></p>
<pre><code>람다로 표현해보자</code></pre><pre><code class="language-python">    reduce(lambda x, y: x + y, range(1, 6))  # 15

    # 팩토리얼도 가능하다
    reduce(lambda x, y: x * y, range(1, 6))</code></pre>
<pre><code>얼마나 간소해졌을까</code></pre><pre><code class="language-python">    # 단순 서술
    def my_sum(x, y):
        return x + y

    total_sum = 0
    for i in range(1, 6):
        total_sum += i
    print(total_sum)  # 15</code></pre>
<pre><code class="language-python">    reduce(lambda x, y: x + y, range(1, 6))</code></pre>
<blockquote>
<p>reduce로 식을 엄청 간소화 시킬 수 있는것을 확인했다.
    하지만 이 reduce는 코드가 복잡해질 수록 코드가 무엇을 의미하는지 파악이 힘들어지는 부분이 있어 Python 3 부터는 reduce 를 내장함수에서 제거했다고 한다</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[리스트, 튜플 정리]]></title>
            <link>https://velog.io/@aiffel-hj/%EB%A6%AC%EC%8A%A4%ED%8A%B8-%ED%8A%9C%ED%94%8C-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@aiffel-hj/%EB%A6%AC%EC%8A%A4%ED%8A%B8-%ED%8A%9C%ED%94%8C-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Thu, 30 Dec 2021 09:33:00 GMT</pubDate>
            <description><![CDATA[<h2 id="리스트-list">리스트 (list)</h2>
<blockquote>
<p>타 프로그래밍 언어에서의 <code>배열</code> 과 같다.
<strong>변형이 가능</strong>한 <em>mutable object</em> 이다.
리스트의 <strong>크기</strong>를 제한하여 선언하지 않는다. <strong>자료형</strong>을 제한하지 않는다.</p>
</blockquote>
<pre><code class="language-java">// Java
String[] arr = new String[5];</code></pre>
<pre><code class="language-python"># Python
arr = []
arr2 = [1, &quot;3&quot;, True, datetime.datetime.now(), (5, 1), {&quot;a&quot;:&quot;A&quot;, &quot;b&quot;:&quot;B&quot;}]</code></pre>
<h3 id="요소-추가하기-append-extend-insert">요소 추가하기 .append() .extend() .insert()</h3>
<ol>
<li><p>.append()</p>
<p> <img src="https://images.velog.io/images/aiffel-hj/post/cdcc7d1b-c70f-4734-a9b2-8565c9fd8fa9/Untitled.png" alt=""></p>
</li>
</ol>
<pre><code class="language-python">    a = [1, 2, 3]
    a.append(5)
    print(a)

    &gt;&gt;&gt; Output
    [1, 2, 3, 5]</code></pre>
<blockquote>
<p>파이썬의 리스트는 길이를 제한하여 선언하지 않으니 인덱스 형식으로 덧붙일 순 없을까?
    → <strong><em>No!</em></strong></p>
</blockquote>
<pre><code class="language-python">    a = [1, 2, 3]
    # 다음번 추가 될 인덱스는 a[3] 이다.
    a[3] = 4

    &gt;&gt;&gt; Output
    IndexError: list assignment index out of range

    # 대신, 아래 방법으로 대체가 가능하다.
    a[3:] = [4]</code></pre>
<blockquote>
<p>파이썬에서 배열에 집어넣을 때(치환이 아니라면) .append()를 활용하자!</p>
</blockquote>
<ol start="2">
<li><p>extend()</p>
<p> <img src="https://images.velog.io/images/aiffel-hj/post/9e7ec5f7-8af9-4a1e-aee0-a0c4de7922a7/Untitled%201.png" alt=""></p>
</li>
</ol>
<pre><code class="language-python">    a = [1, 2, 3]
    a.extend([4, 5])  # a += [4, 5] 도 같은 효과
    print(a)

    &gt;&gt;&gt; Output
    [1, 2, 3, 4, 5]</code></pre>
<blockquote>
<p><strong><em>Tip!</em></strong>
    + 연산도 .extend()와 동일한 결과를 만든다.
    a, b = [1, 2, 3], [4, 5]
    print(a + b) → [1, 2, 3, 4, 5]
     <strong>+= 도 역시 먹힌다.</strong>
     a += b
     print(a) → [1, 2, 3, 4, 5]</p>
</blockquote>
<ol start="3">
<li><p>insert()</p>
<p> <img src="https://images.velog.io/images/aiffel-hj/post/1eb4ce24-ce77-4068-9ead-2dbbd30f7130/Untitled%202.png" alt=""></p>
</li>
</ol>
<pre><code class="language-python">    a = [0, 1, 2]
    a.insert(1, 10)
    print(a)

    &gt;&gt;&gt; Output
    [0, 10, 1, 2]</code></pre>
<blockquote>
<p>그럼 하나만 삽입하는게 아니라 extend 처럼 많은 요소를 덧붙일 순 없을까?
    a.insert(1, [6, 7, 8])</p>
</blockquote>
<pre><code class="language-python">    a.insert(1, [6, 7, 8])
    # 기대값: a = [0, 10, 1, 2] 였으므로, [0, 6, 7, 8, 10, 1, 2] 이지 않을까?
    print(a)

    &gt;&gt;&gt; Output
    [0, [6, 7, 8], 10, 1, 2]</code></pre>
<p>그럴 땐 리스트 슬라이싱을 활용해서 더해버리자.</p>
<pre><code class="language-python">    # CASE 1
    a = [0, 1, 2]
    b = a[0:1] + [6, 7, 8] + a[1:]
    print(b)

    # CASE 2
    c = [0, 1, 2]
    c[1:1] = [6, 7, 8]
    print(c)

    &gt;&gt;&gt; Output
    [0, 6, 7, 8, 1, 2]
    [0, 6, 7, 8, 1, 2]

    &quot;&quot;&quot;
    b = a[0:1]
    b.extend([6, 7, 8])
    b.extend(a[1:])

    위 extend 방식보다 +가 훨씬 간결하다.
    &quot;&quot;&quot;</code></pre>
<h3 id="요소-삭제하기-pop-과-del-키워드">요소 삭제하기 .pop() 과 del 키워드</h3>
<ol>
<li>.pop()</li>
</ol>
<blockquote>
<p>대상 데이터를 리스트에서 지우고 어떤 값이었는지 리턴한다.</p>
</blockquote>
<p><img src="https://images.velog.io/images/aiffel-hj/post/b23c7f1f-f330-49d6-b89e-b1453a0bf948/Untitled%203.png" alt=""></p>
<pre><code class="language-python">    # .pop()에 인자가 없으면 마지막걸 지운다
    a = [1, 4, 3, 9]
    a.pop()
    print(a)

    # .pop(n)은 n번째 인덱스를 지운다.
    b = [2, 5, 6, 7]
    b.pop(2)
    print(b)

    &gt;&gt;&gt; Output
    [1, 4, 3]
    [2, 5, 7]</code></pre>
<ol start="2">
<li>del</li>
</ol>
<blockquote>
<p>리스트에서 대상 데이터를 어떠한 리턴 없이 지운다</p>
</blockquote>
<pre><code class="language-python">    a = [1, 4, 3, 9]
    del a[-1]  # 맨 마지막
    print(a)

    b = [2, 5, 6, 7]
    del b[2]
    print(b)

    c = [7, 8, 9, 0]
    del c[1:2]  # 범위 지정해서 제거도 가능!
    print(c)

    &gt;&gt;&gt; Output
    [1, 4, 3]
    [2, 5, 7]
    [7, 0]</code></pre>
<ol>
<li>두가지는 언제 쓰이나?(리턴 유무가 다르다)</li>
</ol>
<pre><code class="language-python">    # 1~ 45까지 숫자가 적힌 종이가 통안에 있다.
    # 이때, 무작위로 한장을 뽑아 발표하고 뽑은 종이는 통에서 제거한다.

    import random

    numbers = list(range(1, 46))
    random.shuffle(numbers)

    # Case 1) del 사용
    # 범위 삭제 가능!
    # 딕셔너리에서도 사용 가능!
    pop_num = numbers[0]  # 값을 사전에 할당하고
    del numbers[0]  # 지워야 한다.
    print(f&quot;첫 당첨번호는 {pop_num} 입니다!&quot;)

    # Case 2) .pop() 사용
    # 두줄보단 한줄이 간결하니까..!
    # 한번에 하나씩만 삭제 가능!
    pop_num = numbers.pop()  # 통에서 제거한 당첨번호 리턴

    print(f&quot;다음 당첨번호는 {pop_num} 입니다!&quot;)
    print(pop_num in numbers)  # 뽑은 번호는 통에 없다

    &gt;&gt;&gt; Output
    첫 당첨번호는 32 입니다!
    다음 당첨번호는 11 입니다!
    False</code></pre>
<h3 id="특정-값의-인덱스-찾기-index">특정 값의 인덱스 찾기 .index()</h3>
<pre><code class="language-python">a = [5, 10, 15, 10, 35, 20]
print(a.index(10))

&gt;&gt;&gt; Output
1</code></pre>
<blockquote>
<p>리스트에 찾으려는 값이 여러 개 있더라도 가장 처음 찾은 인덱스를 반환(작은 수)</p>
</blockquote>
<ul>
<li>타겟숫자 모두 삭제시키기(0 제거)</li>
</ul>
<pre><code class="language-python">    arr = [0, 10, 0, 13, 10, 15, 0, 0, 7]
    del_target = 0
    find_index = False
    while del_target in arr:
        del arr[arr.index(del_target)]  # or arr.pop(a.index(del_target))
    print(arr)

    &gt;&gt;&gt; Output
    [10, 13, 10, 15, 7]</code></pre>
<h3 id="특정-값의-갯수-구하기-count">특정 값의 갯수 구하기 .count()</h3>
<pre><code class="language-python">arr = [10, 20, 30, 15, 20, 40]
print(arr.count(20))

&gt;&gt;&gt; Output
2</code></pre>
<h3 id="정렬하기-sort">정렬하기 .sort()</h3>
<pre><code class="language-python">a = [10, 20, 30, 15, 20, 40]
a.sort()
print(a)

&gt;&gt;&gt; Output
[10, 15, 20, 20, 30, 40]</code></pre>
<h3 id="순서-뒤집기-reverse">순서 뒤집기 .reverse()</h3>
<pre><code class="language-python">a = [10, 20, 30, 15, 20, 40]
a.reverse()
print(a)

&gt;&gt;&gt; Output
[40, 30, 20, 20, 15, 10]</code></pre>
<blockquote>
<p>반복문에서 range() 와 함께 역순으로 값을 받기위해 사용한 reversed() 와 다르다!
[ list ].reverse()  &lt; &gt;  <strong>reversed</strong>(range(10))</p>
</blockquote>
<blockquote>
<p>개인적으론..
정렬을 하는 경우가 list, dictionary 에서 많은데, sorted() 함수로 통일해서 쓰는 편.
sorted(a) # 오름차순
sorted(a, reverse=True) # 내림차순
sorted({  ... dict  }, key=lambda x: x[1], reverse=True)</p>
</blockquote>
<h3 id="초기화-clear">초기화 .clear()</h3>
<pre><code class="language-python">a = [10, 20, 30, 15, 20, 40]
a.clear()
print(a)

b = [10, 20, 30, 15, 20, 40]
del b[:]  # [(처음부터):(끝까지)]
print(b)

&gt;&gt;&gt; Output
[]
[]</code></pre>
<h3 id="기타">기타</h3>
<ul>
<li>리스트가 비어있는지 판단?</li>
</ul>
<pre><code class="language-python">    arr = [1, 2, 3]
    if arr:
        print(&quot;arr은 비어있지 않네요&quot;)

    &quot;&quot;&quot;
    if len(arr) &gt; 0: 와 동치이다.
    대상 리스트의 원소갯수를 세고, 갯수가 0 초과이면(비어있지 않다면?)
    &quot;&quot;&quot;

    arr2 = []
    if not arr:
        print(&quot;arr은 비어있군요&quot;)

    &gt;&gt;&gt; Output
    arr은 비어있지 않네요
    arr은 비어있군요</code></pre>
<ul>
<li>리스트 내에 n 이 있는지 확인</li>
</ul>
<pre><code class="language-python">    arr = [1, 2, 3]

    # Case 1) .index() 활용
    # .index()는 찾을 대상이 없으면 Exception 발생
    try:
        if arr.index(1):
            print(&quot;리스트에 &#39;1&#39;이 있어요&quot;)
    except ValueError:
        print(&quot;리스트에 &#39;1&#39;은 없어요&quot;)

    # Case 2) in 활용
    # 찾을 대상이 리스트에 없어도 예외가 발생하지 않는다.
    if 1 in arr:
        print(&quot;리스트에 &#39;1&#39;이 있어요&quot;)
    else:
        print(&quot;리스트에 &#39;1&#39;은 없어요&quot;)</code></pre>
<ul>
<li>리스트 내 중복제거</li>
</ul>
<pre><code class="language-python">    arr = [10, 20, 10, 15, 20, 40]
    arr = list(set(arr))  # [40, 10, 20, 15]</code></pre>
<h2 id="mutable-object의-복사에-대해">mutable object의 복사에 대해</h2>
<blockquote>
<p>mutable 객체는 재 할당 시 주의해야 한다. a를 b에 대입하여 선언하면 값만 복사되는게 아니다.
<strong><em>실제로 흔하게 하는 실수!!!!</em></strong></p>
</blockquote>
<p>예를 들면</p>
<pre><code class="language-python">&quot;&quot;&quot;
1~10 까지 숫자를 가지는 numbers1, numbers2를 만든다
단, numbers2 의 앞 5개 원소는 2배씩 증가시켜 저장한다. 이때, numbers1 은 보존되어야 한다.
&quot;&quot;&quot;
numbers1 = list(range(1, 11))  # 1. 1~10까지 리스트에 할당
numbers2 = numbers1  # 2. numbers2에 numbers1의 사본이 생겼겠지?

for i in range(5):
    numbers2[i] *= 2

print(numbers1)
print(numbers2)

&gt;&gt;&gt; Guess
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]  # numbers1
[2, 4, 6, 8, 10, 6, 7, 8, 9, 10]  # numbers2

&gt;&gt;&gt; Output
[2, 4, 6, 8, 10, 6, 7, 8, 9, 10]  # numbers1도 같이 변해버렸다?
[2, 4, 6, 8, 10, 6, 7, 8, 9, 10]</code></pre>
<p>각 변수의 id를 확인해보면 같은 값이다.</p>
<pre><code class="language-python">print(f&quot;numbers1의 id는 {id(numbers1)} 입니다&quot;)
print(f&quot;numbers2의 id는 {id(numbers2)} 입니다&quot;)

&gt;&gt;&gt; Output
numbers1의 id는 140573167644800 입니다
numbers2의 id는 140573167644800 입니다</code></pre>
<p>이런 상황이 발생하지 않으려면? .copy() 메소드로 복사하자</p>
<pre><code class="language-python">numbers1 = list(range(1, 11))  # 1. 1~10까지 리스트에 할당
numbers2 = numbers1.copy()  # 2. numbers2에 numbers1과 같은 값이지만 다른 id를 가진다

&quot;&quot;&quot;
아니면 또 쓰기..
numbers2 = list(range(1, 11))
&quot;&quot;&quot;

for i in range(5):
    numbers2[i] *= 2

print(f&quot;id: {id(numbers1)}, {numbers1}&quot;)
print(f&quot;id: {id(numbers2)}, {numbers2}&quot;)

&gt;&gt;&gt; Output
id: 140704004809600, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
id: 140704004809536, [2, 4, 6, 8, 10, 6, 7, 8, 9, 10]  # id도 다르고 numbers2만 바뀌었다.</code></pre>
<h2 id="리스트-표현식list-comprehension">리스트 표현식(List comprehension)</h2>
<blockquote>
<p>[ ] 리스트 괄호 안에 요소들이 열거되지 않고 for 와 if 가 쓰여있다면 리스트 표현식이 사용된 것</p>
</blockquote>
<pre><code class="language-python"># 1) for만 이용한 표현법
arr = [i for i in range(10)]  # arr = [0, 1, 2, ... 9]
# for 에서 반복되며 생성된 i가 배열에 대입된다.

# 2) 그럼 여기에서 가중치를 줄 수 있나?
arr2 = [i+1 for i in range(10)]  # arr2 = [1, 2, 3, ... 10]

# 3) 여기에서 혹시 조건을 줄 수 있나? 짝수만 담을래
arr3 = [i for i in range(10) if i % 2 == 0]

# 주의)
arr4 = [i+1 for i in range(10) if i % 2 == 0]
# 여기에서 i+1이 대입되지만, if에서 비교하는 i 와는 다르다. (i &lt;&gt; i+1)
# 타이핑 상 대입부를 먼저 기록하다보면 햇갈릴 수 있음!</code></pre>
<p><img src="https://images.velog.io/images/aiffel-hj/post/94b92400-0d8e-44bb-8534-99b12eed309a/Untitled%204.png" alt=""></p>
<ul>
<li>리스트 표현식을 안쓴것과 얼마나 다르지?</li>
</ul>
<pre><code class="language-python">    # Case 1: 리스트 표현식
    arr1 = [i+1 for i in range(10) if i % 2 == 0]

    # Case 2: 상세 기술
    arr2 = []
    for i in range(10):
        if i % 2 == 0:
            arr2.append(i+1)</code></pre>
<blockquote>
<p>조건이 복잡해지면 리스트 표현식으로는 한계가 있다. 가급적 단순한 것들만!</p>
</blockquote>
<ul>
<li>반복문 중첩</li>
</ul>
<pre><code class="language-python">    gugudan = [f&quot;{x}x{y}={x*y}&quot; for x in range(2, 10) for y in range(1, 10)]
    print(gugudan)

    &quot;&quot;&quot;
    gugu = []
    for x in range(2, 10):
        for y in range(1, 10):
            gugu.append(f&quot;{x}x{y}={x*y}&quot;)
    &quot;&quot;&quot;

    &gt;&gt;&gt; Output
    [&#39;2x1=2&#39;, &#39;2x2=4&#39;, ... &#39;9x9=81&#39;]</code></pre>
<ul>
<li>반복문 중첩에서 조건은?</li>
</ul>
<pre><code class="language-python">    # m x n 일때, m은 짝수, n은 홀수만 기록하면?
    gugudan = [
        f&quot;{x}x{y}={x*y}&quot;
        for x in range(2, 10)
        for y in range(1, 10)
        if x % 2 == 0 and y % 2 == 1
    ]
    # 마지막 조건부에서 중첩 for의 x, y 모두 가져와 비교할 수 있다.
    print(gugudan)

    &gt;&gt;&gt; Output
    [&#39;2x1=2&#39;, &#39;2x3=6&#39;, &#39;2x5=10&#39;, &#39;2x7=14&#39;, &#39;2x9=18&#39;, &#39;4x1=4&#39;, &#39;4x3=12&#39;, &#39;4x5=20&#39;, &#39;4x7=28&#39;, &#39;4x9=36&#39;, &#39;6x1=6&#39;, &#39;6x3=18&#39;, &#39;6x5=30&#39;, &#39;6x7=42&#39;, &#39;6x9=54&#39;, &#39;8x1=8&#39;, &#39;8x3=24&#39;, &#39;8x5=40&#39;, &#39;8x7=56&#39;, &#39;8x9=72&#39;]</code></pre>
<ul>
<li>리스트 표현식이 만능은 아님</li>
</ul>
<pre><code class="language-python">    # 0 ~ 9 까지 수를 가지는 리스트
    x = [i for i in range(10)]
    y = list(range(10))
    print(x, y)

    # &quot;hello world&quot; 를 Hello World로 출력하기 위해 &quot;Hello&quot;, &quot;World&quot; 로 전처리 해두기
    x = [i.capitalize() for i in &quot;hello world&quot;.split()]
    y = list(map(lambda i: i.capitalize(), &quot;hello world&quot;.split()))
    print(x, y)</code></pre>
<h2 id="튜플tuple">튜플(tuple)</h2>
<blockquote>
<p>리스트와 유사하지만 변형이 불가능한 <em>immutable object</em> 이다.
리스트가 [ ] 대괄호 였다면, 튜플은 ( ) 괄호 이다.</p>
</blockquote>
<p>기본적으로 튜플은 선언 후 변형할 수 없다.</p>
<pre><code class="language-python">a = (1, 2, 3)
print(a[2])  # Output &gt;&gt; 2
a[2] = 5  # 대입할 수 없다.

&gt;&gt;&gt; Output
TypeError: &#39;tuple&#39; object does not support item assignment</code></pre>
<p>위 리스트와 다른 점만 살펴본다면, 이해가 빠르지 않을까..?</p>
<h3 id="리스트와-비교표">리스트와 비교표</h3>
<p><img src="https://images.velog.io/images/aiffel-hj/post/e90b1e4f-9e9b-4a16-bc2b-89f1056b4465/Untitled%205.png" alt=""></p>
<h3 id="부득이하게-새-값을-추가해야-할-경우">부득이하게 새 값을 추가해야 할 경우</h3>
<p>매번 새로 선언할 순 없으니..</p>
<pre><code class="language-python"># 기존 리스트와 비교를 위해
list_a = [1, 2, 3]
print(f&quot;더하기 전 id: {id(list_a)}&quot;)
list_a.append(5)
print(f&quot;더한 후 id: {id(list_a)}&quot;)  # 동일한 id가 찍힌다.
print(list_a)  # [1, 2, 3, 5]

# 튜플은?
tuple_a = (1, 2, 3)
print(f&quot;더하기 전 id: {id(tuple_a)}&quot;)  # 140573721050432
tuple_a += (5,)  # tuple_b = tuple_a + (5, 6, 7)
print(f&quot;더한 후 id: {id(tuple_a)}&quot;)  # 140573718939184. 다른 id가 찍힌다
print(tuple_a)  # (1, 2, 3, 5)</code></pre>
<blockquote>
<p><strong><em>Tip!</em></strong>
튜플은 무조건 새로 생성된다고 보면 된다.
이때, 덧붙일 원소가 하나만 있을 수 있다. 위처럼 (5,) 로 표현되어 있는데 이는 (5)가 일반 괄호인지 튜플표현인지 구분이 힘들어서인데, 원소가 하나일 땐 꼭 콤마를 찍어주자!</p>
</blockquote>
<h3 id="튜플의-표현식">튜플의 표현식</h3>
<p>튜플도 리스트 표현식과 동일한 방법으로 사용할 수 있다.</p>
<p>다만 몇가지 주의사항이 있는데</p>
<ol>
<li>단순 괄호( )만 사용하면 안된다.</li>
</ol>
<pre><code class="language-python">    list_comp = [i+1 for i in range(10) if i % 2 == 0]
    print(list_comp)  # [1, 3, 5, 7, 9]

    # [] 를 () 로만 치환하면 되겠지?
    tuple_comp = (i+1 for i in range(10) if i % 2 == 0)
    print(tuple_comp)  # &lt;generator object &lt;genexpr&gt; at 0x7fabf6377e40&gt;</code></pre>
<p>웬 처음보는 generator가 나오는데, 나중에 배울 개념이므로 pass..
아무튼, 단순괄호는 제너레이터 표현식이 되어버린다.</p>
<ol start="2">
<li>괄호가 아니라 <strong><em>tuple()</em></strong> 이다</li>
</ol>
<pre><code class="language-python">    tuple_comp = tuple(i+1 for i in range(10) if i % 2 == 0)
    print(tuple_comp)  # (1, 3, 5, 7, 9)</code></pre>
<h2 id="map함수-이터레이터-이해">map([함수], [이터레이터]) 이해</h2>
<blockquote>
<p>이터레이터에서 발생한 원소를 함수에 대입하여 이터레이터로 반환한다.</p>
</blockquote>
<pre><code class="language-python"># date란 문자열이 있습니다.
# 년 월 일에 해당하는 숫자를 모두 더해 출력하세요
date_str = &quot;2021. 12. 30&quot;

# Case 1. for문 활용하기
total = 0
for i in date_str.split(&quot;. &quot;):
    total += int(i)
print(total)

# Case 2. map 활용하기
total = sum(map(int, date_str.split(&quot;. &quot;)))
print(total)</code></pre>
<blockquote>
<p>해설</p>
</blockquote>
<ol>
<li>.split() 에서 뽑히는 2021, 12, 30 각 문자를</li>
<li>int 함수에 대입하여준다.
→ sum( [ int(”2021”), int(”12”), int(”30”) ] )<blockquote>
</blockquote>
</li>
</ol>
<h2 id="max-min-sum">max(), min(), sum()</h2>
<p>리스트와 튜플 모두 사용할 수 있다.
원소들 중 가장 큰 값, 가장 작은 값, 전체 합을 구할 수 있는 기본 함수를 제공하고 있다.</p>
<pre><code class="language-python">list_ = [10, 20, 30, 40, 50]
tuple_ = (20, 10, 40, 30, 50)

max(list_)  # 50
min(tuple_)  # 10
sum(list_) + sum(tuple_). # 300</code></pre>
<blockquote>
<p>파이썬 기본함수엔 avg() 같은 평균을 구하는 함수는 없다.
avg = sum(list_) / len(list_)</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[반복문 이해하기]]></title>
            <link>https://velog.io/@aiffel-hj/%EB%B0%98%EB%B3%B5%EB%AC%B8-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@aiffel-hj/%EB%B0%98%EB%B3%B5%EB%AC%B8-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 29 Dec 2021 09:20:44 GMT</pubDate>
            <description><![CDATA[<h2 id="for-문">For 문</h2>
<blockquote>
<p><em>정해진 횟수</em>만큼 반복한다.</p>
</blockquote>
<h3 id="1-각-언어별-for문-비교">1. 각 언어별 for문 비교</h3>
<ul>
<li>C</li>
</ul>
<pre><code class="language-c">    for (int i = 0; i &lt; 10; i++)  // 0부터 9까지 증가하면서 10번 반복
    {
        printf(&quot;%d\n&quot;, i);
    }

    &gt;&gt;&gt; Output
    0
    1
    2
    ...
    9</code></pre>
<ul>
<li>C#</li>
</ul>
<pre><code class="language-csharp">    for (int i=0; i&lt;10; i++)  // 0부터 9까지 증가하면서 10번 반복
    {
        Console.WriteLine(i.toString())
    }
    &gt;&gt;&gt; Output
    0
    1
    2
    ...
    9</code></pre>
<ul>
<li>Java</li>
</ul>
<pre><code class="language-java">    for (int i=0; i&lt;10; i++)
    {
        System.out.println(i);
    }
    &gt;&gt;&gt; Output
    0
    1
    2
    ...
    9</code></pre>
<ul>
<li>Javascript</li>
</ul>
<pre><code class="language-jsx">    for (let i=0; i&lt;10; i++)
    {
        console.log(i)
    }
    &gt;&gt;&gt; Output
    0
    1
    2
    ...
    9</code></pre>
<h3 id="2-python-에서의-표현range-활용">2. Python 에서의 표현(range 활용)</h3>
<p><img src="https://images.velog.io/images/aiffel-hj/post/6d27c390-b937-4a53-b4dc-6854785d8e1a/Untitled.png" alt=""></p>
<ul>
<li><p>초기값을 2부터 시작하고 싶다면?</p>
<pre><code class="language-python">  for i in range(2, 10):
          print(i)

  &gt;&gt;&gt; Output
  2
  3
  ...
  9</code></pre>
</li>
<li><p>건너뛰는건 할 수 없을까?</p>
<pre><code class="language-python">  for i in range(2, 10, 2):
          print(i)

  &gt;&gt;&gt; Output
  2
  4
  6
  8</code></pre>
</li>
<li><p>거꾸로도 하고 싶은데?</p>
<pre><code class="language-python">  for i in reversed(range(0, 10, 2)):
          print(i)

  &gt;&gt;&gt; Output
  8
  6
  ...
  0</code></pre>
</li>
<li><p>range 뿐만 아니라 list, tuple, dictionary, string 등 제한된 데이터들도 반복 가능..!</p>
</li>
</ul>
<pre><code class="language-python">    for s in &quot;hi!&quot;:
        print(s)
    &gt;&gt;&gt; Output
    h
    i
    !

    hello = &quot;hello&quot;  # 문자열도 배열처럼 취급 가능..!
    print(hello[1])
    &gt;&gt;&gt; Output
    e

    for i in [1, 2]:
        print(i)
    &gt;&gt;&gt; Output
    1
    2

    for i in (4, 6):
        print(i)
    &gt;&gt;&gt; Output
    4
    6

    for key in {&quot;a&quot;: 1, &quot;b&quot;: 2}:
        print(key)
    &gt;&gt;&gt; Output
    a
    b</code></pre>
<h2 id="while-문">While 문</h2>
<blockquote>
<p>정해진 횟수를 특정할 수 없을 때 활용
반복의 조건을 명확히 명시하거나, break 문을 활용해야 한다.</p>
</blockquote>
<p><img src="https://images.velog.io/images/aiffel-hj/post/1bc48be2-79dd-47f6-9ac3-e853f650c3c5/Untitled%20(1).png" alt=""></p>
<blockquote>
<p><strong><em>break란?</em></strong>
반복문을 즉시 중단 시킨다.</p>
</blockquote>
<ul>
<li>조건을 부여한다면</li>
</ul>
<pre><code class="language-python">    i = 0
    while i &lt; 10:
         print(i)
         i += 1

    &gt;&gt;&gt; Output
    0
    1
    ...
    9</code></pre>
<blockquote>
<p><strong><em>Tip!</em></strong>
     Python에서 ++ 연산자는 사용할 수 없다.(1씩 증가)
     i++  ⇒   <strong>i += 1</strong></p>
</blockquote>
<ul>
<li>무한루프에서 break문 활용</li>
</ul>
<pre><code class="language-python">    i = 0
    while True:
         print(i)
         i += 1
         if i &gt;= 9:
             break

    &gt;&gt;&gt; Output
    0
    1
    ...
    9</code></pre>
<h2 id="반복문은-중첩-할-수-있다">반복문은 중첩 할 수 있다</h2>
<blockquote>
<p>반복문 구문 내 반복문을 정의하면 반복을 중첩 할 수 있다.</p>
</blockquote>
<h3 id="for-문으로-구구단을-표현-해보자">for 문으로 구구단을 표현 해보자</h3>
<pre><code class="language-python">for i in range(2, 10):  # 2~9단까지!
    for j in range(1, 10):  # nx1 ~ nx9 까지!
        print(i, &quot;x&quot;, j, &quot;=&quot;, i*j)

&gt;&gt;&gt; Output
2 x 1 = 2
2 x 2 = 4
...
6 x 3 = 18
6 x 4 = 24
...
9 x 9 = 81</code></pre>
<blockquote>
<p><strong><em>Tip!</em></strong>
print() 문을 사용할 때, 변수와 스트링을 콤마로 연결할 수 있다.</p>
</blockquote>
<h3 id="while-문으로-구구단을-표현-해보자">While 문으로 구구단을 표현 해보자</h3>
<ol>
<li>무한루프로 한다면?</li>
</ol>
<pre><code class="language-python">    i, j = 2, 1  # 변수 여러개를 한줄에 선언할 수 있다!
    while True:
        j = 1  # 다음 단으로 넘어갈 때 j 변수는 초기화 되어야 한다.
        while True:
            print(f&quot;{i} x {j} = {i*j}&quot;)
            j += 1
            if j &gt; 9:  # nx1 ~ nx9 까지!
                break  # 중첩된 반복문 중단
        i += 1
        if i &gt; 9:  # 9단까지 출력
            break  # 첫 반복문 중단</code></pre>
<blockquote>
<p><strong><em>Tip!</em></strong>
    변수를 여러개 선언할 때, 한줄로 선언이 가능하다.
    a, b = “a의 값”, “b의 값”
    좌변과 우변의 갯수가 일치해야 한다.</p>
</blockquote>
<blockquote>
<p><strong><em>Tip!</em></strong>
    스트링에 f 인자를 붙이면 변수를 직접 명시하여 사용할 수 있다.
    print(i, &quot; x &quot;, j, &quot; = &quot;, i<em>j)   vs   print(f&quot;{i} x {j} = {i</em>j}&quot;)
    문자열에 어떤 변수가 어디에 어떻게 쓰였는지 훨씬 직관적이고 짧게 표현이 가능하다</p>
</blockquote>
<ol start="2">
<li>조건을 명시한다면?</li>
</ol>
<pre><code class="language-python">    i, j = 2, 1
    while i &lt; 10:
        j = 1
        while j &lt; 10:
            print(f&quot;{i} x {j} = {i*j}&quot;)
            j += 1
        i += 1</code></pre>
<h2 id="break-continue-의-활용">break, continue 의 활용</h2>
<blockquote>
<p><strong><em>break</em></strong>
반복문을 즉시 중단시킨다</p>
</blockquote>
<blockquote>
<p><strong><em>continue</em></strong>
반복문을 중단시키지 않고 건너뛴다</p>
</blockquote>
<h3 id="구구단으로-활용법-이해하기">구구단으로 활용법 이해하기</h3>
<blockquote>
<p>편의상 for문만 사용합니다. while 문도 원리는 동일!</p>
</blockquote>
<ul>
<li><p>break</p>
<p>  구구단에서 n x 5 까지만 출력하기</p>
</li>
</ul>
<pre><code class="language-python">    for i in range(2, 10):
        for j in range(1, 10):
            print(f&quot;{i} x {j} = {i*j}&quot;)
            if j &gt;= 5:  # n x 6 이상은 출력하지 않는다.
                break  # break 가 아닌 continue 라면 n x 9 까지 연속해서 출력

    &gt;&gt;&gt; Output
    2 x 1 = 2
    ...
    2 x 5 = 10
    3 x 1 = 3
    ...
    9 x 5 = 45</code></pre>
<ul>
<li><p>continue</p>
<p>  구구단에서 짝수단만 출력하기</p>
</li>
</ul>
<pre><code class="language-python">    for i in range(2, 10):
        if i % 2 != 0:
            continue  # n단이 2로 나눠떨어지지 않는 홀수라면 아래 반복문을 건너뛴다
                      # break를 사용했다면, 2단까지만 출력하고 멈춤
        for j in range(1, 10):
            print(f&quot;{i} x {j} = {i*j}&quot;)

    &gt;&gt;&gt; Output
    2 x 1 = 2
    ...
    2 x 9 = 18
    4 x 1 = 4
    ...
    8 x 9 = 72</code></pre>
<hr>
<h2 id="그-외에-알면-도움이-될">그 외에 알면 도움이 될..?</h2>
<p>보통 while은 DB 등에서 Unique Key 등을 생성할 때 활용한다.</p>
<p>ex) 10만개의 중복되지 않는 쿠폰번호를 생성할 때, 랜덤한 문자열이며 중복되지 않아야 한다면?
(반복 횟수를 특정할 수 없을 때! while 문에서 생성한 값을 중복체크한다.)</p>
<p>일반적인 경우엔 for 가 많이 활용 됨.</p>
<p>구구단의 사례에서 처럼 반복문 안에서 if 등으로 멈추고 건너뜀을 제어할 것이 아니라, 애초에 원하는 값만 반복될 수 있도록 하는게 예외도 줄이고 코드 가독성에도 도움이 된다.</p>
<ol>
<li>데이터를 정제하고</li>
<li>for 로 돌린다.</li>
</ol>
<h3 id="list-comprehension-문법-이해하기">List Comprehension 문법 이해하기</h3>
<p>range(n) 은 0부터 n-1 까지의 값을 가진다.</p>
<pre><code class="language-python">list(range(10))

&gt;&gt;&gt; Output
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]</code></pre>
<ul>
<li>짝수만 걸러내기</li>
</ul>
<pre><code class="language-python">    [i for i in range(10) if i % 2 == 0]  # list(range(0, 10, 2)) 와 동일..하긴..ㅎ..

    &gt;&gt;&gt; Output
    [0, 2, 4, 6, 8]</code></pre>
<blockquote>
<p><strong>해설</strong>
    1. [] 리스트로 정의하고
    2. [i for i in range(10)] for 문의 i 는 0 ~ 9 까지 열거되고, 이 i 를 배열에 넣어라!
    3. 이때, i 에 대한 조건을 부여할 수 있는데, i 를 2로 나누었을 때 나머지값이 0이라면? 라는 조건을 부여한다면
    -&gt;&gt;  [i for i in range(10) if i % 2 == 0]</p>
</blockquote>
<ul>
<li><p>조건이 있는 구구단</p>
<p>  n x m 으로 이루어진 구구단을 출력한다.</p>
<p>  단, n은 짝수, m은 홀수여야 한다. n과 m은 1 이상 9 이하여야 한다.</p>
<ul>
<li>반복문 내 조건</li>
</ul>
</li>
</ul>
<pre><code class="language-python">        for n in range(1, 10):
            if n % 2 != 0:
                continue
            for m in range(1, 10):
                if m % 2 != 1:
                    continue
                print(f&quot;{n} x {m} = {n*m}&quot;)</code></pre>
<ul>
<li>List Comprehension 으로 미리 범위 지정</li>
</ul>
<pre><code class="language-python">        c1 = [x for x in range(1, 10) if x % 2 == 0]
        c2 = [x for x in range(1, 10) if x % 2 == 1]

        for n in c1:
            for m in c2:
                print(f&quot;{n} x {m} = {n*m}&quot;)</code></pre>
<ul>
<li>라인수를 줄인다면..</li>
</ul>
<pre><code class="language-python">        for n in [x for x in range(1, 10) if x % 2 == 0]:
            for m in [x for x in range(1, 10) if x % 2 == 1]:
                print(f&quot;{n} x {m} = {n*m}&quot;)</code></pre>
<h2 id="dictionary-의-반복문">Dictionary 의 반복문</h2>
<p>키:벨류 형태의 딕셔너리 변수도 for 문에서 사용이 가능한데</p>
<pre><code class="language-python">data = {
  &quot;한국&quot;: &quot;Republic of Korea&quot;,
  &quot;중국&quot;: &quot;China&quot;,
  &quot;미국&quot;: &quot;The United States of America&quot;,
}

for nation in data:
    print(nation)

&gt;&gt;&gt; Output
한국
중국
미국</code></pre>
<p>위처럼 nation 에 {”한국”: “Republic of Korea”} 이 오길 기대하지만, 키 항목만 오는걸 확인할 수 있는데,
이때 딕셔너리의 .items() 함수를 사용하면</p>
<pre><code class="language-python">for nation in data.items():
    print(nation)

&gt;&gt;&gt; Output
(&#39;한국&#39;, &#39;Republic of Korea&#39;)
(&#39;중국&#39;, &#39;China&#39;)
(&#39;미국&#39;, &#39;The United States of America&#39;)</code></pre>
<p>nation 변수에 튜플형식으로 (키, 벨류) 가 넘어오게 된다. nation[0], nation[1] 로도 접근이 가능하지만 각 키 벨류에 변수명을 할당할 수 있는데,</p>
<pre><code class="language-python">for korean, english in data.items():
    print(f&quot;한국어: {korean} / 영어: {english}&quot;)

&gt;&gt;&gt; Output
한국어: 한국 / 영어: Republic of Korea
한국어: 중국 / 영어: China
한국어: 미국 / 영어: The United States of America</code></pre>
<p>키, 벨류순 으로 열거하여 각 변수에 할당해줄 수도 있다.</p>
<blockquote>
<p><strong><em>Tip!</em></strong>
키만 뽑아내는 data.keys(), 벨류만 뽑아내는 data.values() 도 활용할 수 있다.</p>
</blockquote>
<h3 id="리스트의-인덱스도-함께-알고-싶은데-enumerate">리스트의 인덱스도 함께 알고 싶은데.. enumerate</h3>
<pre><code class="language-python">input_str = &quot;1,2,3,4,5&quot;
for idx, val in enumerate(input_str.split(&quot;,&quot;)):
    print(f&quot;{idx}번째 인덱스에 {val}이 있습니다.&quot;)

&gt;&gt;&gt; Output
0번째 인덱스에 1이 있습니다.
1번째 인덱스에 2이 있습니다.
2번째 인덱스에 3이 있습니다.
3번째 인덱스에 4이 있습니다.
4번째 인덱스에 5이 있습니다.</code></pre>
<p>이렇게 얻은 인덱스를 활용해 정수형으로 치환하기</p>
<pre><code class="language-python">input_str = &quot;1,2,3,4,5&quot;.split(&quot;,&quot;)
for idx, val in enumerate(input_str):
    input_str[idx] = int(val)
print(input_str)

&gt;&gt;&gt; Output
[1, 2, 3, 4, 5]</code></pre>
<h3 id="map-함수-이해하기">map 함수 이해하기</h3>
<p>input_str = &quot;1 2 3 4 5&quot; 일때, 스페이스로 구분하여 각 원소를 정수화 하여 배열에 담기</p>
<pre><code class="language-python"># 1차원적인 방법으로
input_str = &quot;1 2 3 4 5&quot;
numbers = []
for n in input_str.split():
    numbers.append(int(n))
print(numbers)

&gt;&gt;&gt; Output
[1, 2, 3, 4, 5]</code></pre>
<pre><code class="language-python">input_str = &quot;1 2 3 4 5&quot;
numbers = list(map(int, input_str.split()))
print(numbers)

&gt;&gt;&gt; Output
[1, 2, 3, 4, 5]  # 각 원소들이 정수형으로 변환되어 있다.</code></pre>
<blockquote>
<p><strong><em>해설</em></strong></p>
</blockquote>
<ol>
<li>input_str 변수를 .split() 하면 “ “ 를 기준으로 문자열을 잘라 리스트에 넣어준다.
 input_str.split()  →  [”1”, “2”, “3”, “4”, “5”]</li>
<li>리스트의 각 원소들을 int() 함수에 모두 대입해준다.
 [int(”1”), int(”2”), ... int(”5”)]
⇒ [1, 2, 3, 4, 5]<blockquote>
</blockquote>
</li>
</ol>
<ul>
<li>응용</li>
</ul>
<pre><code class="language-python">    # 0 ~ 9 까지의 숫자 중 홀짝 구분하기
    def jjak(n):
        if n % 2 == 0:
            return f&quot;{n}: 짝수&quot;
            else:
            return f&quot;{n}: 홀수&quot;

    # 더 간단하게 표현하면..
    def jjak(n):
        return f&quot;{n}: 짝수&quot; if n % 2 == 0 else f&quot;{n}: 홀수&quot;

    result = list(map(jjak, range(10)))
    print(result)

    &gt;&gt;&gt; Output
    [&#39;0: 짝수&#39;, &#39;1: 홀수&#39;, &#39;2: 짝수&#39;, &#39;3: 홀수&#39;, ... &#39;9: 홀수&#39;]</code></pre>
<blockquote>
<p><strong>해설</strong>
    return f&quot;{n}: 짝수&quot; if n % 2 == 0 else f&quot;{n}: 홀수&quot;
    if n % 2 == 0 이면 f&quot;{n}: 짝수&quot;, 아니면 f&quot;{n}: 홀수&quot;</p>
</blockquote>
<ul>
<li>더 간단히(람다식.. 나중에..!!)</li>
</ul>
<pre><code class="language-python">    result = list(map(lambda n: f&quot;{n}: 짝수&quot; if n % 2 == 0 else f&quot;{n}: 홀수&quot;, range(10)))
    print(result)

    &gt;&gt;&gt; Output
    [&#39;0: 짝수&#39;, &#39;1: 홀수&#39;, &#39;2: 짝수&#39;, &#39;3: 홀수&#39;, ... &#39;9: 홀수&#39;]</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[ls -al 쉽게 사용하기]]></title>
            <link>https://velog.io/@aiffel-hj/ls-al-%EC%89%BD%EA%B2%8C-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@aiffel-hj/ls-al-%EC%89%BD%EA%B2%8C-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 28 Dec 2021 03:18:03 GMT</pubDate>
            <description><![CDATA[<p>리눅스 계열(osx 포함)에서 <code>$ ls -al</code> 명령어를 정말 많이 사용한다.
매번 ls -al 을 입력하기 번거로울 때, <code>$ ll</code> 명령어를 만들어 사용하곤 한다.</p>
<p>이 방법을 모르는 사람이 예상보다 꽤 많아서 정리해본다.</p>
<p>먼저, 터미널에서 참조중인 프로필 파일을 열어줘야 하는데 각 환경별로 파일명이 상이하므로 아래 명령어로 해당하는 파일이 있는지 찾아보자.</p>
<p>프로필 파일은 홈 디렉토리 내에 있다.
<code>$ cd ~</code>
<code>$ ls -al | grep -e profile -e bash -e zsh</code></p>
<p>파일명이 <code>.</code> 으로 시작하는 파일들 중
<code>.profile</code>, <code>.bashrc</code>, <code>.bash_profile</code>, <code>.zshrc</code> 이런 파일들이 보일건데,
존재하는 모든 파일을 수정 할 필요도, 언급한 파일이 없다고 만들 필요도 없다.</p>
<p>우측 파일을 우선적으로 열어주자.
ex) .zshrc, .bashrc 파일 두개가 존재한다면 가장 우측에 있는 .zshrc 열어주기.</p>
<p>에디터는 편의상 vim을 사용.
<code>$ vim .bashrc</code></p>
<p>파일 가장 하단에 아래 명령어를 추가하고 저장한다.
<code>alias ll=&quot;ls -al&quot;</code></p>
<p>그다음 수정해줬던 파일을 터미널에 적용한다.
<code>$ source .bashrc</code></p>
<p>그 다음 터미널에 <code>$ ll</code>을 쳐보면!
ls -al 명령어를 쳤을때와 동일한 화면을 볼 수 있다.</p>
<p>이처럼 alias 명령어를 프로필에 등록해두면 많은 단축 명령어를 활용할 수 있으니 잘 활용해보면 좋을 것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[딥러닝 교육수강 시작]]></title>
            <link>https://velog.io/@aiffel-hj/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B5%90%EC%9C%A1%EC%88%98%EA%B0%95-%EC%8B%9C%EC%9E%91</link>
            <guid>https://velog.io/@aiffel-hj/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B5%90%EC%9C%A1%EC%88%98%EA%B0%95-%EC%8B%9C%EC%9E%91</guid>
            <pubDate>Mon, 27 Dec 2021 09:02:46 GMT</pubDate>
            <description><![CDATA[<p>한번 쯤 딥러닝을 접할 기회가 있었으면 했다.</p>
<p>파이썬으로 밥벌이를 하고 있으면서, 데이터 분야는 건드려 볼 엄두가 나질 않았다. 생이 바쁘단 핑계로..</p>
<p>마침 공백기가 생겼고 아이펠을 알게 되었다.
자기주도학습을 전면에 내건게 가장 마음에 들었다.</p>
<p>매번 이런저런 핑계로 미루던 공부들을 이참에 싹 해보는것도 나쁘지 않을 것 같다.
수학도, 알고리즘도, 딥러닝도.</p>
<p>늘 그래왔듯,
이왕 시작했으니 끝까지 한번 해보자.</p>
<p>과정 후엔 많은게 달라져 있지 않을까?</p>
]]></description>
        </item>
    </channel>
</rss>