콘텐츠로 건너뛰기
Home » 파이썬 » Page 4

파이썬

(파이썬) Counter 사용법

Counter Counter 는 collections 아래에 정의된 사전(dict)의 서브 클래스로 일련의 집합에서 각 원소의 출현 횟수를 세어서 유지한다. 즉 원소:출현빈도의 사전이 생성된다. 생성된 카운터 사전은 일반 사전과 유사하게 키:값 쌍을 추가/삭제하거나 업데이트 할 수 있고, 각 원소를 출현횟수만큼 반복하여 조합해서 복구한다. 텍스트에서 단어의 출현횟수 세기 아래 예제는 특정한 텍스트에서 해당 텍스트를 구성하는 모든 단어와, 그 단어의 출현 빈도를 세는 코드이다.  총 세 가지로 접근한다.  첫 번째 코드는 순수하게 사전만 사용한다. {단어:출현횟수} 로 구성되는 사전에 단어가 있으면 횟수를 +1하고 없으면 값이 1이 되도록 키를… 더 보기 »(파이썬) Counter 사용법

asyncio – 일반 함수를 비동기로 사용하기

지난 글에서 urlopen()과 같은 표준 라이브러리 함수를 어떻게 비동기 코루틴처럼 asyncio에서 사용할 수 있는지 살펴보았다. aiohttp 등의 비동기 라이브러리를 사용해서 여러 핸들러를 작성해야 할 때, 이와 같은 처리를 많이 해야 한다면 빈번하게 런루프 메소드를 호출하는 것보다, 간단히 데코레이터를 만들어서 활용하는 것이 어떨까? asyncio의 이벤트 루프에는 run_in_executor(executor, fn, *args) 가 있다. 이 메소드는 concurrent.futures 모듈의 ThreadPoolExecutor나 ProcessPoolExecutor를 사용하여 일반적인 blocking 함수를 다른 스레드 및 프로세스에서 실행하도록 하고 그 자신은 처리를 기다리는 코루틴을 생성한다. 이 기능을 사용하면 일반적인 blocking-I/O 함수를 non-blocking 함수처럼… 더 보기 »asyncio – 일반 함수를 비동기로 사용하기

람다표현식과 맵, 필터, 리듀스 (Python)

람다(lambda, )는 본래 수리논리학에서의 함수정의를 추상화한 형식 체계로, 간단히 말해서 이름이 없는 함수 혹은 인라인으로 정의하는 함수로 이해할 수 있다. 수학에서의 람다대수의 정의와 비슷하게 파이썬에서는 다음과 같이 람다함수를 정의한다. lambda {파라미터,…} : {표현식} 람다식은 그 자체로 표현식이며 다음 구성 요소로 작성한다. 키워드 lambda 파라미터 : 컴마로 구분되는 1개 이상의 파라미터. 파라미터는 반드시 1개 이상이어어야 한다. 콜론 : 표현식 : 파라미터와 그외 값으로 이루어지는 일련의 표현식 예를 들어 어떤 파라미터 x 에 대해서 1을 증가시킨 값을 구하는 함수는 람다대수로는 이라고 표현하며,… 더 보기 »람다표현식과 맵, 필터, 리듀스 (Python)

functional python에 대한 단상

문득, 이런 생각이 들었다. temp = [] for i in range(10):   temp.append(i*i) 이 코드는 10보다 작은 완전제곱수의 리스트를 만드는 함수다. 빈 리스트를 만들고 range() 로 부터 값을 받아 제곱한 다음, 리스트에 넣는다. 이 과정은 파이썬에 익숙한 사람이라면 반복문 보다는 리스트 축약으로 표현할 것이다. temp = [i*i for i in range(10)] 파이썬 리스트 축약의 기본 컨셉은 어떤 연속열로부터 다른 리스트를 만드는 것이고 이것은 람다식을 연속열에 사상(mapping over)하는 것이다.  다른 예로, 사용자로부터 공백으로 구분되는 숫자들을 받아서 정수 리스트를 만들고자 한다면, 공백으로… 더 보기 »functional python에 대한 단상

프로젝트 오일러 51

두자리 숫자 ▯3 의 첫번째 자리를 여러가지로 바꿨을 때 가능한 아홉가지의 결과 중에서 13, 23, 43, 53, 73, 83의 여섯개는 소수입니다. 56▯▯3의 세 번째와 4번째 자리를 동일한 숫자로 바꿔서 만들어지는 10개의 다섯자리 숫자 중에는 아래에서 보듯이 7개가 소수가 되며, 이것은 이런 식으로 7개의 소수가 만들어지는 첫번째 경우입니다. 이 소수 집단의 첫번째 수인 56003은 이런 성질을 갖는 가장 작은 소수입니다.

56003, 56113, 56333, 56443, 56663, 56773, 56993

위의 예처럼 원래의 일부를 동일한 숫자로 치환했을 때 8개의 소수 집단이 만들어지는 경우를 찾고, 그 집단에 속한 가장 작은 소수를 구하세요. 치환하는 자리는 인접하지 않아도 되고, 가장 앞부분을 치환하는 경우에는 거기에 0은 올 수 없습니다.

http://euler.synap.co.kr/prob_detail.php?id=50
더 보기 »프로젝트 오일러 51

파이썬의 반복문과 iterable에 대해

리스트, 튜플, 문자열, 사전의 공통점은? 모두 for … in 문에 사용할 수 있다는 점이다. 리스트는 for 문을 통해서 개별 원소에 대한 반복 작업을 할 수 있는데, 튜플과 문자열 역시 이와 똑같은 동작을 수행하며 사전의 경우에는 사전 내의 각 키에 대해서 순회하는 기능을 제공한다. 파이썬에서는 이와 같이 for … in 구문을 통해서 반복이 가능한 타입들을 묶어서 iterable이라고 부르는데, 이는 파이썬의 기본 개념에서 매우 중요한 위치를 차지한다. for 문의 백스테이지에 대해 for 문은 일반적인 언어에서의 대표적인 반복문이다. C언어에서는 다음과 같이 쓰인다. 아래… 더 보기 »파이썬의 반복문과 iterable에 대해

asyncio : 단일 스레드 기반의 Nonblocking 비동기 코루틴 완전 정복

asyncio에 의한 단일 스레드 병렬 작업

지난번 concurrent.futures를 소개한 글에서 파이썬 3에서부터 멀티스레딩/멀티프로세싱에 대해 새로 도입된 고수준 API에 대해 살펴봤다. 이 새로운 API는 함수 호출을 병렬로 처리하는 동작을 사용하기 쉽게 만들 뿐 아니라, 직접 스레드를 제어하는 것이 아닌 Future 객체를 사용함으로써 자바스크립트의 Promise 개념을 도입한 것으로 평가할 수 있다고 보았다.

새로운 병렬처리 API와 더불어 Future 클래스가 도입된 것이 파이썬 3.2였다. Future 개념의 도입은 스레드를 관리하고, 다른 스레드에서 돌아가는 작업에 대해서 리턴을 동기화하는 등의 작업들이 매우 골치아팠던 것을 그 자체를 객체로 래핑하면서 매우 우아하게 처리할 수 있었다. 이는 결국 비선형적인 제어 흐름과 관계된 코드를 작성하는 것이 더 이상 너저분한 작업이 아닐 수 있다는 가능성을 보였다.

다중 스레드 및 다중 프로세스에 대해서 Future를 적용하는 것이 성공적이었다면, 이는 단일 스레드에 대해서도 비동기 non-blocking 코드를 작성하는데에 동일한 Future 개념을 도입할 수 있지 않을까하는 것으로 아이디어가 옮겨갔다.

더 보기 »asyncio : 단일 스레드 기반의 Nonblocking 비동기 코루틴 완전 정복

연습문제(벽과 폭탄)

벽과 폭탄

각 테스트 케이스마다 ‘W’, ‘B’로 이루어진 문자열이 입력된다. B는 폭탄을, W는 벽을 의미하는데, 폭탄이 하나 터지면 폭탄을 중심으로 반경 2칸 이내의 벽이 모두 폭파된다. 이 때 폭탄이 일시에 터졌을 때 폭파되는 벽의 개수를 출력하라. (https://www.hackerearth.com/problem/algorithm/bob-and-bombs-cake-walk/description/)

BWW, BW, WB, WWB에 해당하는 W의 수를 세는 문제이므로, 이는 간단하게 정규식으로 해결할 수 있다.
더 보기 »연습문제(벽과 폭탄)

오일러 프로젝트 39

세 변의 길이가 모두 자연수 {a, b, c}인 직각삼각형의 둘레를 p 로 둘 때, p = 120 을 만족하는 직각삼각형은 아래와 같이 세 개가 있습니다.

{20, 48, 52}, {24, 45, 51}, {30, 40, 50}

p가 1000이하일 때, 세변의 길이가 모두 자연수인 직각삼각형을 가장 많이 만들 수 있는 p의 값은 얼마입니까?

http://euler.synap.co.kr/prob_detail.php?id=39
더 보기 »오일러 프로젝트 39

편집거리 (단어의 유사도 분석)

편집거리 구하기

편집거리(edit distance)는 단어의 유사도를 측정하는 방법 중 하나이다. 한 단어에서 글자를 추가/제거/교체하여 다른 단어로 바꿀 때 필요한 최소한의 편집 액션의 횟수로 결정한다.  computer라는 단어와 commuter라는 단어는 매우 유사한데, p -> m으로 한글자만 변경하면 처음 단어에서 두 번째 단어로 바뀌게 된다. 비슷하게 sport라는 단어는 sort라는 단어로 바꾸기 위해서는 p 한글자를 지우면 된다. 혹은 sort에서 p한 글자를 추가하면 된다.

단어의 유사도를 측정하는 방법에는 편집 거리외에도 자카드 유사도 등의 여러 방법이 있다.

편집거리는 두 문자열 s1, s2에서 몇 번의 추가/삭제/변경으로 변환할 수 있는가를 나타내는 개념이다. 이러한 변경에는

  1. 글자를 교환하기
  2. 글자를 삽입하기
  3. 글자를 삭제하기

의 세 종류의 변경 연산을 할 수 있다. 이를 이용해서 두 단어 사이의 편집거리를 구하는 재귀 함수를 생각해보자.

d('', '') = 0 -- 빈 문자열은 0번
d(s, '') = d('', s) = |s| -- 빈문자열로 변경하는데는 s의 길이만큼의 삭제필요
d(s1+ch1, s2+ch2)
 = min( d(s1, s2) + if ch1 = ch2 then 0 else 1, -- 교환
        d(s1+ch1, s2) + 1, -- 삽입
        d(s2, s2+ch2) + 1  -- 삭제
      )

먼저 빈 문자열 두 개 사이의 편집거리는 0이다. 그리고 한글자로 된 문자열과 빈 문자열 간의 편집거리는 당연히 1이다. 그렇다면 빈 문자열과 길이가 n인 문자열의 편집 거리는 n이 된다.
이제 길이가 0이 아닌 두 문자열의 편집거리를 보자. 두 단어 springprint를 예로 들어보겠다.

  1. 변경: sprin + gprin + t로 볼 때 sprin -> prin으로 변경한 후 g -> t로 바꾸는 변경을 1회 수행한다. 이 때 편집거리는 d(sprin, print) + 1이 될 수 있다. 만약 마지막 글자가 동일하다면 1이 아닌 0을 더한다.
  2. 추가: 혹은 springprint + t로 본다면 spring -> prin으로 변경한 후 t를 추가하는 것이므로 편집거리에 1을 더한 d(spring, prin) + 1이 될 수도 있다.
  3. 삭제: 반대로 sprin + gprint로 본다면 sprin -> print로 변경한 후 g를 삭제하는 것이므로 d(sprin, print) + 1이 될 수 있다.

결국 두 단어의 최소 편집 거리는 변경, 추가, 삭제에 의한 결과 중에서 최소값을 사용한다. 그리고 이는 점점 작은 단위로 내려가서 비교하게 되기에 동적계획법으로 풀어낼 수 있다. 이 단계를 추적해보자.더 보기 »편집거리 (단어의 유사도 분석)