{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "*이 노트북은 제이크 반더플라스(Jake VanderPlas)의 [A Whirlwind Tour of Python](http://www.oreilly.com/programming/free/a-whirlwind-tour-of-python.csp)(OReilly Media, 2016)를 기반으로 만들어졌습니다. 이 내용은 [CC0](https://github.com/jakevdp/WhirlwindTourOfPython/blob/master/LICENSE) 라이센스를 따릅니다. 전체 노트북의 목록은 https://github.com/rickiepark/WhirlwindTourOfPython 에서 볼 수 있습니다.*" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "< [기본 데이터 구조](05-기본 데이터 구조.ipynb) | [목차](목차.ipynb) | [함수](08-함수.ipynb) >" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 제어문" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "*제어문*은 프로그래밍에서 아주 중요합니다.\n", "제어문이 없다면 프로그램은 그저 실행문을 순서대로 실행할 뿐입니다.\n", "제어문 때문에 특정 코드 블럭을 조건에 따라서 또는 반복적으로 실행시킬 수 있습니다.\n", "이 기본적인 구성 요소가 연결되면 놀라울 정도로 복잡한 프로그램을 만들 수 있습니다!\n", "\n", "여기에서 *조건문*(\"``if``\", \"``elif``\", \"``else``\")과 *반복문*(\"``for``\"와 \"``while``\" 그리고 부수적으로 \"``break``\", \"``continue``\", \"``pass``\")을 다루겠습니다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 조건문: ``if``-``elif``-``else``:\n", "종종 *if-then* 문이라 불리는 조건문은 불리언 조건에 따라 어떤 코드 블럭을 실행합니다.\n", "기본적인 파이썬의 조건문은 다음과 같습니다:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "-15 는 음수\n" ] } ], "source": [ "x = -15\n", "\n", "if x == 0:\n", " print(x, \"는 0\")\n", "elif x > 0:\n", " print(x, \"는 양수\")\n", "elif x < 0:\n", " print(x, \"는 음수\")\n", "else:\n", " print(x, \"는 내가 본적 없는 어떤 것\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "특히 콜론(``:``)과 공백이 코드 블럭을 정의하는 것을 주목하세요.\n", "\n", "파이썬은 다른 언어에서도 많이 사용하는 ``if``와 ``else``를 사용합니다. 특이한 것은 \"else if\"의 축소판인 ``elif``를 사용합니다.\n", "``elif``와 ``else`` 블럭은 선택적입니다. 또한 원하는 만큼 ``elif``를 포함시킬 수 있습니다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## ``for`` 루프\n", "파이썬은 루프를 사용하여 일부 코드를 반복적으로 실행시킬 수 있습니다.\n", "예를 들어, 리스트에 있는 아이템을 하나씩 출력하기 위해 ``for`` 루프를 사용할 수 있습니다:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2 3 5 7 " ] } ], "source": [ "for N in [2, 3, 5, 7]:\n", " print(N, end=' ') # 같은 줄에 출력합니다" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "``for`` 루프는 단순합니다. 사용할 변수와 반복하기 원하는 시퀀스를 지정하고 \"``in``\" 연산자를 사용하여 직관적이고 읽기 좋게 이 둘을 연결합니다.\n", "조금 더 자세히 말하면 \"``in``\" 연산자의 오른쪽에 있는 객체는 어떤 파이썬의 *반복자*(interator)도 될 수 있습니다.\n", "반복자는 일반화된 시퀀스라고 생각할 수 있습니다. 이에 대해서는 [반복자](10-반복자.ipynb)에서 자세히 다루겠습니다.\n", "\n", "예를 들면, 파이썬에서 가장 널리 사용하는 반복자 중에 하나는 연속된 숫자를 생성하는 ``range`` 객체입니다:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 1 2 3 4 5 6 7 8 9 " ] } ], "source": [ "for i in range(10):\n", " print(i, end=' ')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "범위는 기본적으로 0부터 시작합니다. 관례상 범위의 최댓값은 포함하지 않습니다. Range 객체는 조금 더 복잡한 방식을 지원합니다:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[5, 6, 7, 8, 9]" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 5에서 10까지\n", "list(range(5, 10))" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 2, 4, 6, 8]" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 2씩 건너 뛰면서 0에서 10까지\n", "list(range(0, 10, 2))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "``range`` 매개변수의 의미는 [리스트](06-기본 데이터 구조.ipynb#리스트)에서 다룬 슬라이싱과 매우 비슷합니다.\n", "\n", "``range()`` 함수가 파이썬 2와 파이썬 3의 다른 점 중 하나입니다. 파이썬 2에서는 ``range()``가 리스트를 만들지만 파이썬 3에서는 ``range()``는 반복 객체(iterable object)를 만듭니다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## ``while`` 루프\n", "파이썬의 다른 종류의 루프는 일정 조건이 만족할 때까지 계속 반복하는 ``while`` 루프입니다:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 1 2 3 4 5 6 7 8 9 " ] } ], "source": [ "i = 0\n", "while i < 10:\n", " print(i, end=' ')\n", " i += 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "``while`` 루트의 매개변수는 불리언 표현으로 평가됩니다. 이 표현식이 ``False``로 평가될 때까지 루프가 실행됩니다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## ``break``와 ``continue``: 루프를 세밀하게 조정하기\n", "루프안에서 실행 과정을 세밀하게 조정하기 위해 사용할 수 있는 유용한 두 개의 문장이 있습니다:\n", "\n", "- ``break``는 루프는 완전히 벗어납니다\n", "- ``continue``는 현재 루프의 나머지를 건너뛰고 다음 반복을 진행합니다\n", "\n", "이 두 문장은 ``for``와 ``while`` 루프에 모두 쓸 수 있습니다.\n", "\n", "다음은 ``continue``를 사용하여 홀수를 출력하는 예제입니다.\n", "이 경우 ``if-else`` 문장을 사용해서도 동일한 결과를 만들 수 있지만 ``continue``가 아이디어를 표현하는데 조금 더 편리할 수 있습니다:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 3 5 7 9 11 13 15 17 19 " ] } ], "source": [ "for n in range(20):\n", " # n / 2의 나머지가 0이면, 루프의 나머지를 건너 뜁니다\n", " if n % 2 == 0:\n", " continue\n", " print(n, end=' ')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "다음은 조금 더 쉬운 문제에 사용된 ``break``의 예시입니다.\n", "이 루프는 특정 값까지의 피보나치(Fibonacci) 수열을 리스트에 채우는 것입니다:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]\n" ] } ], "source": [ "a, b = 0, 1\n", "amax = 100\n", "L = []\n", "\n", "while True:\n", " (a, b) = (b, a + b)\n", " if a > amax:\n", " break\n", " L.append(a)\n", "\n", "print(L)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "``break`` 문이 없는 ``while True`` 루프를 사용하면 영원히 반복될 것입니다!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## ``else`` 블럭이 있는 루프\n", "\n", "파이썬에서 드물게 사용되는 패터는 ``for``나 ``while`` 루프에 ``else`` 문을 사용하는 것입니다.\n", "앞서 ``else`` 블럭에 대해 이야기 했습니다. 이 블럭은 ``if``와 ``elif`` 문이 ``False``로 평가될 때 실행됩니다.\n", "루프에서 ``else``는 파이썬에 있는 혼돈을 일으킬만한 이름 중 하나입니다. ``nobreak``라고 생각하는 것이 좋습니다. 즉 ``else`` 블럭은 ``break`` 문을 거치지 않고 루프가 자연적으로 종료됐을 때에만 실행됩니다.\n", "\n", "이 문장이 유용한 한 가지 예로 다음 소수를 찾기 위해 잘 알려진 *에라토스테네스의 체*(Sieve of Eratosthenes) 알고리즘의 (최적화되지 않은) 구현을 생각해 보겠습니다([에라토스테네스의 체 위키문서 참조](https://ko.wikipedia.org/wiki/%EC%97%90%EB%9D%BC%ED%86%A0%EC%8A%A4%ED%85%8C%EB%84%A4%EC%8A%A4%EC%9D%98_%EC%B2%B4)):" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]\n" ] } ], "source": [ "L = []\n", "nmax = 30\n", "\n", "for n in range(2, nmax):\n", " for factor in L:\n", " if n % factor == 0:\n", " break\n", " else: # no break\n", " L.append(n)\n", "print(L)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "``else`` 문은 나눌 수 있는 수가 없는 경우에만 실행됩니다. ``while`` 루프에서도 비슷하게 ``else``가 동작합니다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "< [기본 데이터 구조](05-기본 데이터 구조.ipynb) | [목차](목차.ipynb) | [함수](08-함수.ipynb) >" ] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "TensorFlow 2.3 on Python 3.6 (CUDA 10.1)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.9" } }, "nbformat": 4, "nbformat_minor": 1 }