KalelPark's LAB

[ CLEAN CODE ] Dictionary defaultdict, Closure in local function? 본문

Python/CLEAN CODE

[ CLEAN CODE ] Dictionary defaultdict, Closure in local function?

kalelpark 2023. 3. 14. 09:36

Dictionary

     - 일반적으로, Dictionary의 원소 삽입 순서와 iteration 순서는 일치하지 않는다.

        이러한 일이 발생하는 이유는, Dictionary의 구현이 내장 hash와 난수 씨앗값(seed)을 사용하는

        해시 테이블 알고리즘이기 때문이다.

 

     - 만약 dictionary를 순서에 의존하고 싶다면, 아래와 같은 명령어를 사용하면 됩니다.

baby_names = {
	"cat" : "kitten",
    "dog" : "puppy"
}

print(baby_names.keys())
print(baby_names.values())
print(baby_names.items())
print(baby_names.popitem())

기존 방법에서는, dictionary에서 값을 불러올 때, 순서대로 불러오지 않았습니다.

하지만, items를 활용하면 값을 순서대로 불러오는 것이 가능합니다.

def my_func(**kwargs):
    for key, values in kwargs.items():
        print(f"{key} = {values}")

my_func(goose = "gosling", kangoroo = "joey")

class도 마찬가지입니다.

class MyClass:
    def __init__(self):
        self.agen = "hatching"
        self.roba = "calf"

roba = MyClass()
for key, value in roba.__dict__.items():
    print(f"{key} = {value}")

>> result
// agen = hatching
// roba = calf

 

* Python에서 in을 자주 사용하고, key가 없을 경우에는, KeyError를 처리하기보다는 get을 활용하여 처리하는 것이 좋습니다.

  첫 번째 if문에서는 for문을 반복해서 2번 돌아, 상당한 시간이 걸립니다.

  하지만, 아래의 try, except문은 한번의 반복문이 돌아 상당한 시간복잡도 단축을 할 수 있습니다.

counters = {
    "alpha":1,
    "beta":2
}

key = "temp"

if key in counters:
    counters[key] += 1
else:
    counters[key] = 1

# solving
try:
    count = counters[key]
except KeyError:
    counters[key] = 1

python collections 내장 모듈에 존재하는 defaultdict 클래스는 키가 없을 때, 자동으로 디폴트 값을 저장해서 용법을 효율적으로 처리하게 해줍니다.

from collections import defaultdict

class Visits:
    def __init__(self):
        self.data = defaultdict(set)
    
    def add(self, country, city):
        self.data[country].add(city)

visits = Visits()
visits.add("영국", "버스")
visits.add("영국", "런던")

print(visits.__dict__.items())


// dict_items([('data', defaultdict(<class 'set'>, {'영국': {'버스', '런던'}}))])

defaultdict를 효율적으로 처리하기 위한, 방법론입니다.

https://dongdongfather.tistory.com/69

 

[파이썬 기초] 유사 딕셔너리 defaultdict() 활용법

defaultdict()는 딕셔너리를 만드는 dict클래스의 서브클래스이다. 작동하는 방식은 거의 동일한데, defaultdict()는 인자로 주어진 객체(default-factory)의 기본값을 딕셔너리값의 초깃값으로 지정할 수 있

dongdongfather.tistory.com

파이썬에서 함수를 처리할 때, 4개의 값 이상 언패킹하지 말 것을 말합니다.

만약 4개의 이상의 값을 언패킹하는 경우, 혼동되기 쉬울 뿐 아니라, 반환 값이 많으면 실수하기도 쉬워진다.

또한, 가장 중요한 가독성이 떨어진다.

def get_avg_ratio(numbers):
    average = sum(numbers) / len(numbers)
    scaled = [x / average for x in numbers]
    scaled.sort(reverse = True)
    
    return scaled

longest, *middle, shortest = get_avg_ratio(lengths)

우선순위를 만드는 코드이다., 파이썬이 closure(클로저)를 지원받아, 클로저를 활용함으로써 영역 밖의 변수를 참조하여, 발생된 것이다.

# 우선순위 함수 만들기
def sort_priority(values, group):
    def helper(x):
        if x in group:          # making priority
            return (0, x)
        return (1, x)
    
    values.sort(key = helper)

numbers = [8, 3, 1, 2, 5, 4, 7, 6]
group = {2, 3, 5, 7}
sort_priority(numbers, group)
print(numbers)

 

Comments