{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "***\n", "***\n", "# 10. 리스트의 활용\n", "***\n", "***" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "***\n", "## 1 리스트 정렬하기\n", "***" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1-1 리스트의 sort 메소드\n", "- L.sort() 함수는 리스트 L 자체를 변경하며 리턴값을 반환하지 않는다." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "None\n", "[1, 2, 3, 4, 5, 8, 9]\n" ] } ], "source": [ "L = [1, 5, 3, 9, 8, 4, 2]\n", "print L.sort()\n", "print L" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 파이썬은 디폴트로 cmp(a, b) 내장 함수를 이용하여 정렬 방식을 결정한다.\n", "- cmp(a, b)\n", " - if a < b: return -1\n", " - if a > b: return 1\n", " - if a == b: return 0" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "-1\n", "1\n", "0\n" ] } ], "source": [ "print cmp(1,2)\n", "\n", "print cmp(5,2)\n", "\n", "print cmp('abc', 'abc')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 기본 정렬 방식을 변경하려면 cmp(a, b)와 같은 비교 함수를 직접 만들어서 sort() 함수의 인자로 넣는다." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[6, 5, 4, 3, 2, 1]\n" ] } ], "source": [ "def mycmp(a1, a2): # 대소관계에 따른 순서를 반대로 바꾸었음\n", " return cmp(a2, a1)\n", "\n", "L = [1, 5, 3, 2, 4, 6]\n", "L.sort(mycmp) # 역순으로 정렬\n", "print L" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 여러 튜플을 요소로 지닌 리스트인 경우, 튜플의 첫번째 값이 아닌 다른 위치에 있는 값을 기준으로 정렬 " ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "sorted by name: [('jung', 10, 36), ('kim', 3, 28), ('lee', 5, 38)]\n", "sorted by experience: [('kim', 3, 28), ('lee', 5, 38), ('jung', 10, 36)]\n", "sorted by age: [('kim', 3, 28), ('jung', 10, 36), ('lee', 5, 38)]\n" ] } ], "source": [ "def cmp_1(a1, a2):\n", " return cmp(a1[1], a2[1])\n", "\n", "def cmp_2(a1, a2):\n", " return cmp(a1[2], a2[2])\n", "\n", "L = [ ('lee', 5, 38), ('kim', 3, 28), ('jung', 10, 36)]\n", "L.sort()\n", "print 'sorted by name:', L\n", "\n", "L.sort(cmp_1)\n", "print 'sorted by experience:', L\n", "\n", "L.sort(cmp_2)\n", "print 'sorted by age:', L" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- sort() 함수 인자로 reverse 값을 받을 수 있다.\n", " - 디폴트 reverse 인자값은 False\n", " - reverse 인자값을 True로 주면 역순으로 정렬됨" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[9, 8, 6, 6, 3, 2, 1]\n" ] } ], "source": [ "L = [1, 6, 3, 8, 6, 2, 9]\n", "L.sort(reverse = True)\n", "print L" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- sort() 함수 인자로 key에 함수를 넣어줄 수 있다.\n", " - key 인자에 함수가 할당되어 있으면 각 리스트 원소에 대해 비교함수 호출 직전에 key 함수를 먼저 호출한다. " ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['123', '2345', '34', '56']\n", "['34', '56', '123', '2345']\n" ] } ], "source": [ "L = ['123', '34', '56', '2345']\n", "L.sort()\n", "print L\n", "\n", "L.sort(key=int)\n", "print L" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1-2 sorted 내장 함수\n", "- sorted() 내장함수는 L 자체에는 내용 변경 없이 정렬이 되어진 새로운 리스트를 반환한다." ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 2, 3, 6, 6, 8, 9]\n", "[1, 6, 3, 8, 6, 2, 9]\n" ] } ], "source": [ "L = [1, 6, 3, 8, 6, 2, 9]\n", "newList = sorted(L)\n", "print newList\n", "print L" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 2 3 6 6 8 9\n" ] } ], "source": [ "for ele in sorted(L):\n", " print ele," ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- sorted() 함수의 두번째 인자로 cmp 함수 지정 가능" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[6, 5, 4, 3, 2, 1]\n", "[1, 5, 3, 2, 4, 6]\n" ] } ], "source": [ "def mycmp(a1, a2): # 대소관계에 따른 순서를 반대로 바꾸었음\n", " return cmp(a2, a1)\n", "\n", "L = [1, 5, 3, 2, 4, 6]\n", "print sorted(L, mycmp) # 역순으로 정렬\n", "print L" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 인자로 reverse와 key 지정 가능" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[9, 8, 6, 6, 3, 2, 1]\n", "['34', '56', '123', '2345']\n" ] } ], "source": [ "L = [1, 6, 3, 8, 6, 2, 9]\n", "print sorted(L, reverse=True)\n", "\n", "L = ['123', '34', '56', '2345']\n", "print sorted(L, key=int)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1-3 L.reverse() 와 reversed() 내장 함수\n", "- L.reverse()도 반환값이 없다.\n", " - 즉, L 자체를 역순으로 뒤집는다.\n", " - [주의] 역순 정렬이 아니다." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "None\n", "[9, 2, 6, 8, 3, 6, 1]\n" ] } ], "source": [ "L = [1, 6, 3, 8, 6, 2, 9]\n", "print L.reverse()\n", "print L" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "11 4 8 10 5 8 3\n", "[1, 6, 3, 8, 6, 2, 9]\n" ] } ], "source": [ "L = [1, 6, 3, 8, 6, 2, 9]\n", "L.reverse() # 역순으로 뒤집는다.\n", "for ele in L:\n", " print ele + 2,\n", "\n", "print\n", "L.reverse() # 다시 원상태로 복귀시킨다.\n", "print L" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- reversed() 내장함수는 sorted() 처럼 내용이 뒤집힌 리스트를 반환한다.\n", " - sorted() 처럼 원래 리스트 내용에는 변함없다." ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 6, 3, 8, 6, 2, 9]\n", "11 4 8 10 5 8 3\n", "[1, 6, 3, 8, 6, 2, 9]\n" ] } ], "source": [ "L = [1, 6, 3, 8, 6, 2, 9]\n", "print L\n", "for ele in reversed(L):\n", " print ele + 2, \n", "print\n", "print L" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "***\n", "## 2 리스트 내포(List Comprehension)\n", "***\n", "- 일반적인 리스트 생성법" ] }, { "cell_type": "code", "execution_count": 74, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n" ] } ], "source": [ "L = []\n", "for k in range(10):\n", " L.append(k*k)\n", " \n", "print L" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 위 코딩은 리스트 내포 리터럴 방식을 활용해서 아래와 같이 변경할 수 있다." ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n" ] } ], "source": [ "L = [k * k for k in range(10)]\n", "print L" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 리스트 내포 리터럴\n", "
\n",
    "[expression for expr1 in sequence1\n",
    "              for expr2 in sequence2 \n",
    "              ...\n",
    "              for exprN in sequenceN\n",
    "              if condition]\n",
    "
\n", "- expression의 평가 결과 반드시 한 개의 원소가 나와야 한다.\n", " - 틀린 예: [ x, y for x in seq1 for u in seq2 ]\n", "- 만약 두 개의 이상의 평가 결과가 나오면 튜플 등으로 감싸 주어야 한다.\n", " - 올바른 예: [ (x, y) for x in seq1 for u in seq2 ]\n", "- 위 리터럴은 다음의 일반적인 for 문의 리털러과 동일\n", "
\n",
    "l = []\n",
    "for expr1 in sequence1:\n",
    "  for expr2 in sequence2:\n",
    "      ...\n",
    "         for exprtN in sequenceN:\n",
    "            if condition:\n",
    "               l.append(expression)\n",
    "
\n", " " ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 9, 25, 49, 81]\n" ] } ], "source": [ "L = [k * k for k in range(10) if k % 2] # 홀수의 제곱만 리스트로 형성\n", "print L" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 위의 리스트 내포 코드는 아래와 동일" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 9, 25, 49, 81]\n" ] } ], "source": [ "L = []\n", "for k in range(10):\n", " if k%2:\n", " L.append(k*k)\n", "print L" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 20보다 작은 2의 배수와 3의 배수에 대해 그 두 수의 합이 7의 배수인 것들에 대해 그 두 수의 곱을 출력하는 코드" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[(2, 12, 24), (4, 3, 12), (6, 15, 90), (8, 6, 48), (10, 18, 180), (12, 9, 108), (16, 12, 192), (18, 3, 54)]\n" ] } ], "source": [ "L = [(i, j, i*j) for i in range(2, 20, 2) for j in range(3, 20, 3) if (i + j) % 7 == 0]\n", "print L" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 두 개의 시퀀스 자료형에 대해 각각의 원소에 대한 쌍을 튜플 형태로 만들면서 리스트에 저장하는 코드" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[('a', 1), ('a', 2), ('a', 3), ('b', 1), ('b', 2), ('b', 3), ('c', 1), ('c', 2), ('c', 3)]\n" ] } ], "source": [ "seq1 = 'abc'\n", "seq2 = (1, 2, 3)\n", "print [(x, y) for x in seq1 for y in seq2]" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['THE', 'the', 3]\n", "['QUICK', 'quick', 5]\n", "['BROWN', 'brown', 5]\n", "['FOX', 'fox', 3]\n", "['JUMPS', 'jumps', 5]\n", "['OVER', 'over', 4]\n", "['THE', 'the', 3]\n", "['LAZY', 'lazy', 4]\n", "['DOG', 'dog', 3]\n" ] } ], "source": [ "words = 'The quick brown fox jumps over the lazy dog'.split()\n", "stuff = [[w.upper(), w.lower(), len(w)] for w in words]\n", "for i in stuff:\n", " print i" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

참고 문헌: 파이썬(열혈강의)(개정판 VER.2), 이강성, FreeLec, 2005년 8월 29일

" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.1" } }, "nbformat": 4, "nbformat_minor": 1 }