EasyDict는 Python에서 제공하는 유틸리티로, 딕셔너리(dictionary)의 키(key)를 속성(attribute)처럼 사용할 수 있도록 해주는 기능을 제공합니다. 일반적인 딕셔너리에서는 키에 접근하기 위해 인덱싱을 사용해야 하지만, EasyDict를 사용하면 점(.) 표기법으로 더 간결하고 직관적인 코드를 작성할 수 있습니다. 예를 들어, 일반 딕셔너리 config가 있고, 그 안에 key로 learning_rate이 있다고 가정합시다. 딕셔너리에서는 config["learning_rate"]처럼 접근해야 하는데, 이게 좀 지저분해 보여서 가독성이 떨어집니다. EasyDict에서는 config.learning_rate와 같이 깔끔한 방식으로 사용할 수 있습니다.

 

 

EasyDict는 JSON이나 중첩된 딕셔너리 데이터를 다룰 때 특히 유용합니다. 중첩된 구조의 데이터에서도 각 키에 속성처럼 접근할 수 있어 코드의 가독성과 유지보수성을 높입니다. 예를 들어, config.model.type처럼 중첩된 키를 점 표기법으로 접근할 수 있습니다. 또한, 기존 딕셔너리 메서드(keys(), values() 등)와의 호환성을 유지하기 때문에 기존의 딕셔너리와 동일하게 동작합니다. 새로운 키를 추가하거나 값을 수정하는 것도 속성 접근 방식으로 간단하게 처리할 수 있습니다.

 

하지만 EasyDict는 일부 제약사항도 가지고 있습니다. 예를 들어, 딕셔너리의 메서드 이름(keys, values 등)과 동일한 이름의 키를 사용할 경우, 해당 키 대신 메서드가 반환될 수 있습니다. 이 경우에는 일반적인 딕셔너리 인덱싱 방식(config["keys"])으로 해당 키에 접근해야 합니다. 또한, 특정 라이브러리에서 표준 딕셔너리만 지원할 경우 EasyDict를 사용하기 어려울 수 있으며, 이런 상황에서는 dict()를 사용해 다시 표준 딕셔너리로 변환해야 합니다.

 

EasyDict는 머신러닝이나 딥러닝 프로젝트에서 설정 파일을 다루는 데 자주 사용됩니다. 모델의 하이퍼파라미터, 데이터 경로, 학습 설정 등을 저장하고, 이를 코드에서 직관적으로 불러오는 데 적합합니다. 예를 들어, 모델의 설정 파일을 EasyDict로 관리하면, config.learning_rate나 config.dataset.path와 같은 방식으로 값을 불러올 수 있어 코드가 훨씬 간결해집니다. 또한, JSON 데이터를 로드한 뒤 EasyDict로 변환하면 JSON 객체를 더 Pythonic하게 다룰 수 있습니다.

 

EasyDict는 pip install easydict 명령을 통해 간단히 설치할 수 있으며, 딕셔너리를 기반으로 속성 접근 방식을 제공하기 위해 Python의 dict를 상속받아 구현되었습니다. 이를 통해 기존 딕셔너리와의 호환성을 유지하면서도 속성 접근 방식의 편리함을 제공합니다. 이러한 특징 때문에 EasyDict는 JSON 처리, 설정 관리, 그리고 복잡한 데이터 구조를 다루는 많은 Python 프로젝트에서 널리 사용되고 있습니다.

반응형
LIST

Dictionary: unpacking 2개 dictionary를 unpacking해서 1개 dictionary로 합치기

 
d1 = {'a': 2, 'b': 3}
d2 = {'c': 4, 'd': 5}
 
res = {**d1, **d2}
 
  • Dictionary를 unpacking하려면 ** 사용
  • res는 새롭게 만들어진 dictionary
  • res 안에는 d1과 d2가 합쳐진 것이 들어간다.
 

중복된 key를 가지는 dictionary들의 unpacking 후 합치기

 
d1 = {'a': 2, 'b': 3}
d2 = {'b': 4, 'c': 5}
 
res = {**d1, **d2}
  • d1과 d2는 서로 같은 key 'b'를 가지고 있음
  • res에는 1개의 key 'b'만 존재
  • 'b' : 4 값을 가져서, 나중에 들어온 key가 이전 것을 override
반응형
LIST

Python에서 tuple 만드는 방법

 
Tuple은 만들어진 후 수정할 수 없는 리스트
 
Comma (콤마)를 사용해서 숫자들을 나열하면 tuple (튜플)이 된다.
t = 1, 2
  • 숫자 2개로 이루어진 tuple
 
t = 1,
  • 숫자 1개로 이루어진 tuple.
  • 반드시 comma 끝에 있어야 한다.
 
t = ()
  • Empty tuple을 만든다.
 

Unpacking tuple (언팩킹 튜플)

 
Tuple의 값들을 개별 변수에 할당: 이 작없을 unpacking이라고 한다.
 
a, b, c = 1, 2, 3
  • Tuple (1,2,3)에 대해서, a, b, c에 각각 1, 2, 3을 할당한다.
  • 왼쪽에는 tuple 표시 ( )를 하지 않아도 된다.
 
t = 1, 2, 3
a, b, c = t
  • Tuple t를 만들고, unpacking해도 된다.
 

Unpacking을 이용한 변수 값 바꾸기

변수 a, b에 들어있는 값을 서로 바꾸는 python 방식
 
a, b = 1, 2
a, b = b, a
 

Unpacking할 때 변수 갯수가 맞지 않을 때

 
  1. 첫 번째 방법
 
  • Tuple에 3개 값이 있는데, 2개 변수에만 unpacking하고 싶을 때는, underscore(_)를 사용한다
 
a, b, _ = 1, 2, 3
 
 
  1. 두 번째 방법: 1개 변수를 튜플로 만든다.
 
  • 왼쪽 변수에 *을 사용한다.
 
a, *b = 1, 2, 3
 
  • a = 1, b = (2,3)이 된다.
  • b type은 list가 된다.
 

Tuple 자체를 풀어버리는 * operator (연산자)

Tuple a와 b를 풀어서 하나로 합치는 방법
 
*a : tuple unpacking
 
리스트도 unpacking이 된다.
 
a = 1, 2
b = 3, 4
c = *a, *b
  • c는 tuple이고, c = (1, 2, 3, 4)가 된다.
 
c = [*a, *b]
  • c는 list이고, c = [1, 2, 3, 4]가 된다.
 
 
반응형
LIST

개요

 

문자열에서 내가 원하는 정보만을 추출해 낼 때, 정규식 (regular expression)을 사용하면 편리하다.


 

문제

다음과 같은 문자열 S가 있다고 하자.

2022-07-28 14:06:24;[DEBUG]    Epoch 9 학습시작. LR=[2.4471741852423235e-05]

 

S에는 epoch에 대한 정보와 LR에 대한 정보가 담겨있다.

즉, epoch=9, LR=2.44... 이다.

S를 파싱해서 이 정보들만을 추출해 보도록 하자.


구현

 

- 정규식을 이용하려면 모듈 re가 필요하다.

import re

 

- 정보를 담고 있는 문자열 S를 만든다.

S = '2022-07-28 14:06:24;[DEBUG]    Epoch 9 학습시작. LR=[2.4471741852423235e-05]'

 

- 추출하고 싶은 정보가 무엇인지, 정규식으로 표현한다.

regex = re.compile(r'Epoch (\d+)')

    . Epoch 이라는 문자열이 있고, 

    . \d 는 0 ~ 9까지의 숫자를 의미

    . \d+ 는 1개 이상의 숫자로 구성된 문자열을 의미

    . (\d+) 는 ( )는 내가 추출을 원하는 정보임을 표시

    . regex에는 추출하고자 하는 것이 무엇인지에 대한 정보가 담긴다.

 

- regex를 이용해서 S를 검색한다. 

matchobj = regex.search(S)

    . matchobj에는 추출 결과들이 담겨있다.

 

- matchobj에서 내가 원하는 정보만을 꺼내면 된다.

epoch = int(matchobj.group(1))

    . matchobj.group(1)은 추출된 것 중에서 첫 번째 정보를 의미한다.

    . int ( ...) 는 추출된 것이 문자열이기 때문에 정수로 변환

 

- 이번에는 LR 정보를 추출하기 위한 정규식을 만들어 보자

regex = re.compile(r'LR=\[(.+)\]')

    . \[, \]는 양 옆의 괄호 문자를 의미한다.

    . .(period)는 모든 문자를 의미

    . .+ : 1개 이상의 모든 문자.

 

- LR을 추출하는 코드는 위와 동일하다.

matchobj = regex.search(S)
lr = float(matchobj.group(1))

    . float( )는 추출된 문자열을 실수로 바꾸어주는 것이다.

 


아래는 regular expression(정규식)에서 사용되는 meta characters(메타 문자)들이다.

반응형
LIST

ㅇ 네이버에서 제공하는 실시간 인기 검색어를 프로그램에서 자동으로 가져오는 방법에 대해서 설명합니다.
  - 여기서는 실시간 검색어 제공 페이지의 html을 간략히 분석하고,
  - python 언어를 이용해서 검색어를 추출하는 방법을 설명합니다.

ㅇ 우선, 네이버에서 제공하는 실시간 인기검색어 URL과 웹브라우저에서 보이는 내용을 캡쳐해 보았습니다.
  -  이 URL에서 실시간으로 검색어 순위를 제공합니다.
  - 제공되는 형태는 아래와 같습니다만, 여기서는 일부분만 화면 캡쳐했기 때문에
  - 실제로는 훨씬 더 많은 내용이 보여집니다.


ㅇ 주의할 점은
  - 네이버 페이지 개편 작업 등을 하면 URL이 바뀔 수도 있고,
  - URL은 맞아도, 내용이나 포맷이 변경될 수도 있습니다.
  - 그 경우에는 여기서 설명하는 내용이 맞지 않을 수도 있습니다.
  - 하지만, 여기서 설명하는 방법을 이해하면,
  - 그러한 변경에 맞춰 추출하는 방법을 수정할 수 있습니다.

HTML 분석: 추출하는 방법을 설명하기 전에, 
  - 실시간 검색어 순위 페이지의 HTML 코드를 볼 줄 알아야합니다.
  - 아래에는 검색어 순위에 해당하는 부분의 코드만 캡쳐해 놓았습니다.
  - ul tag 들 중에서, class attribute가 'rank_list'를 가진 것이 실시간 검색어를 가지고 있습니다. 
  - 일단 이 ul tag를 찾기만 하면, 
  - 그 안에 span tag들이 여러 개 들어있는데, 이 tag의 값들이 모두 검색어에 해당합니다.
  - span tag들은 모두 20개 있고,
  - 이것은 실시간 상위 검색어 20에 해당합니다.


ㅇ Beautiful Soup
  - python에서는 HTML 문서 파싱을 아주 쉽게 할 수 있는 beautiful soup 모듈을 제공합니다.
  - 이 모듈은 html 문서를 tree구조로 만들에서,
  - 손쉽게 원하는 영역을 찾고, 특정 값을 추출할 수 있도록 합니다.
  - 이 프로그램도 beautifulsoup을 이용할 것입니다.

ㅇ 프로그램 구조
  - 아주 간단합니다.
  - 네이버 실시간 검색어 페이지를 다운로드 받고,
  - 결과를 파싱해서, 실시간 검색어 20개를 찾아내어 출력합니다.

ㅇ 실시간 검색어 페이지 다운로드
  - Python에서 제공하는 requests 모듈을 이용하면 1줄로 짤 수 있습니다.
  - 아래 코드의 line 30에 해당하는 부분입니다.

ㅇ HTML 파싱
  - 이제 Beautifulsoup이 등장할 순서입니다.
  - 다운로드 받은 웹페이지를 파싱하는데, 
  - 이것도 1줄이면 됩니다.
  - 아래 코드의 line 32에 해당합니다.

ㅇ 검색어 부분 추출
  - 이것도 간단하게 생각하면 됩니다.
  - 앞서 HTML 구조에서 설명했듯이, ul tag 들 중에서 class attribute가 'rank_list'인 것만 찾으면 된다.
  - 이 과정은 line 37 ~ 48에 해당합니다.
   
ㅇ 검색어만 출력하기
  - ul tag 안에 들어있는
  - span tag 들을 모두 찾으면,
  - 그 tag의 contents가 바로 실시간 검색어입니다.
  - span tag는 모두 20개이고, 상위 20개 인기 검색어에 해당합니다.
  - 이 과정은 line 50 ~ 55에 해당합니다.

ㅇ 파싱과정에서 다소 지저분한 디테일들과 한글처리 관련 주의사항이 있는데,
  - 아래 코드의 comment에 설명해 놓았습니다.
  - 코드는 바로 붙여넣기 한 후에 실행할 수 있습니다.
  - 다만, Beautifulsoup이 없다면, 먼저 설치해야 합니다.
    . 설치 방법에 대해서는 인터넷을 검색하면 됩니다. 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# -*- coding: utf-8 -*-

# 네이버 실시간 검색어 크롤링 
# 
# 네이버에서 제공하는 실시간 인기 검색어 상위 20개를
# 자동추출하는 프로그램 
#
# 크롤이 대상 웹페이지: 아래 주소에서 실시간 검색어 정보를 얻을 수 있다.
# URL: http://datalab.naver.com/keyword/realtimeList.naver?where=main
# 
# 찾는 방법: 읽어 온 문서를 파싱해서 검색어를 찾는 과정은 다음과 같다.
# ul tag를 모두 찾고,
# class attribute가 rank_list인 것을 찾고,
# span tag안에 들어있는 실시간 검색어를 추출
#
#
# 사용모듈
# requests: HTTP request와 response, 네트워크를 통해웹페이지 접속
# BeautifulSoup: 웹페이지를 파싱 
#
# 주의사항: 
# Beautiful soup이 반환하는 값은 배열 안에 들어가 있음
# index[0]이 맨 앞에 들어 있는 값임.
#
#
import requests
from bs4 import BeautifulSoup

# 실시간 검색어를 제공하는 웹이지를 읽음
response = requests.get('http://datalab.naver.com/keyword/realtimeList.naver?where=main')
# 웹페이즈를 파싱
dom = BeautifulSoup(response.text, 'html.parser')

#print(response.text)  # for debugging

# ul tag를 모두 찾음
result = dom.find_all('ul')

#print result # for debugging

for res in result:
    
    #print(str(res['class']))  # for debugging
    #print "-------------------------\n"  # for debugging

    # 실시간 검색어를 출력한다.
    # class attribute의 값이 rank_list인 경우에,
    if res['class'][0] == 'rank_list':
        # 검색어가 들어있는 span tag를 모두 찾아서,
        keywords = res.find_all('span')
        # span tag의 contents 중 첫번째 [0] 요소를 출력하면 된다.
        # 한글을 올바르게 출력하기 위해서는 
        # 이 파일의 맨 위에 utf-8 coding임을 코멘트로 명시
        for key in keywords:  # 상위 20개의 실시간 검색어가 들어있다.
            print key.contents[0]
        break


ㅇ 위의 Python 코드를 실행한 결과입니다.
  - 20개의 실시간 인기 검색어가 나온 것을 볼 수 있습니다.







반응형
LIST

+ Recent posts