defaultdict(list)와 딕셔너리 컴프리헨션으로 같은 키의 값 그룹화하고 빈도 확인하기
·
Python
왜 이 내용을 정리하나로그 파일에서 사용자 ID별로 요청 기록을 모으거나, 판매 데이터에서 지역별 주문 목록을 나누는 일은 실무에서 자주 나온다. 같은 키를 가진 값들을 하나의 리스트로 모아 두면 이후에 개수를 세거나 합계를 내거나 정렬하기가 쉬워진다. 이런 작업은 반복문에서 키 존재 여부를 매번 검사하는 코드로도 할 수 있지만, 코드가 길어지고 실수가 생기기 쉽다. 그래서 collections 모듈의 defaultdict와 딕셔너리 컴프리헨션을 함께 쓰는 방법을 정리해 둘 필요가 있다.이 노트에서는 defaultdict(list)로 키별 리스트를 만드는 방법, 그 결과를 딕셔너리 컴프리헨션으로 가공하는 방법, 그리고 리스트 길이로 빈도를 확인하는 방법을 정리해 본다.개념 설명일반 딕셔너리에서 없는 키에..
yield가 있는 함수 호출 시 본문 미실행과 제너레이터 객체 반환 확인하기 (inspect.isgeneratorfunction, type())
·
Python
왜 이 내용을 정리하나파이썬에서 함수 안에 yield가 있으면 일반 함수처럼 동작하지 않는다. 함수를 호출하는 순간 본문 코드가 한 줄도 실행되지 않고, 제너레이터 객체만 돌아온다. 이 사실을 모르고 코드를 짜면 print가 안 찍히는 이유를 찾느라 시간을 낭비하기 쉽다. 특히 디버깅 중에 함수의 반환값을 확인할 때, 값이 나오지 않고 객체만 보여 당황하는 경우가 많다. 그래서 이 동작을 직접 확인할 수 있는 방법을 알아 둘 필요가 있다. 이 노트에서는 inspect.isgeneratorfunction과 type()으로 이 동작을 확인하는 방법을 정리해 본다.개념 설명함수 정의 안에 yield 키워드가 하나라도 있으면, 파이썬은 그 함수를 제너레이터 함수로 취급한다. 일반 함수는 호출하면 본문을 처음부터..
Python 함수 기본 인자에 가변 리스트를 쓸 때 호출 사이에 값이 유지되는 이유와 확인 방법
·
Python
왜 이 내용을 정리하나Python으로 함수를 만들다 보면 기본 인자에 빈 리스트를 넣는 경우가 많다. 결과 목록을 쌓거나, 캐시를 흉내 내거나, 옵션을 담을 때 자연스럽게 떠오르는 방식이다. 그런데 이렇게 짠 함수를 여러 번 호출하면 앞선 호출에서 넣은 값이 다음 호출에도 남아 있는 것처럼 보이는 일이 생긴다. 처음 보는 사람에게는 함수가 상태를 기억하는 것처럼 느껴져서 원인을 찾기 어렵다. 이 노트에서는 기본 인자가 언제 만들어지는지, 호출 사이에 값이 유지되는 이유가 무엇인지, 그리고 이를 직접 확인하는 방법을 정리해 본다.개념 설명Python에서 함수의 기본 인자 값은 함수를 호출할 때마다 새로 만들어지지 않는다. 함수가 정의되는 시점, 즉 def 문이 실행되는 시점에 한 번 계산되어 함수 객체의 ..
제너레이터 표현식으로 파일 줄을 지연 평가하며 빈 줄과 주석 줄 건너뛰기
·
Python
왜 이 내용을 정리하나설정 파일이나 로그 파일을 읽어 처리하는 스크립트를 만들다 보면, 파일 안에 빈 줄과 주석 줄이 섞여 있는 경우가 대부분이다. 이런 줄을 걸러내는 가장 단순한 방법은 파일 전체를 리스트로 읽은 뒤 조건문으로 거르는 것이다. 그런데 파일이 수 기가바이트에 이르면 리스트 하나가 메모리를 모두 차지한다. 이때 제너레이터 표현식을 여러 단계로 이어 붙이면 한 번에 한 줄씩만 처리하면서도 같은 결과를 얻을 수 있다. 이 노트에서는 빈 줄과 주석 줄을 건너뛰는 흐름이 실제로 어떻게 지연 평가되는지 확인해 본다.개념 설명제너레이터 표현식은 대괄호 대신 소괄호로 감싼 식이다. 리스트 컴프리헨션이 결과를 즉시 만들어 메모리에 담는 것과 달리, 제너레이터 표현식은 값을 요구받을 때 하나씩 계산한다. ..
Python 딕셔너리 컴프리헨션으로 리스트를 키-값 쌍으로 바꾸고 중복 키 동작 확인하기
·
Python
왜 이 내용을 정리하나리스트로 받은 데이터를 조회하기 쉬운 딕셔너리로 바꾸는 작업은 실무에서 자주 나온다. API 응답에서 ID 목록을 받아 이름을 찾거나, CSV 한 줄씩 읽은 레코드를 키 기준으로 정리하거나, 설정 값 목록을 이름으로 찾는 상황이 대표적이다. 이때 딕셔너리 컴프리헨션을 쓰면 반복문 없이 한 줄로 변환할 수 있다. 다만 같은 키가 여러 번 나오면 어떤 값이 남는지 모르고 쓰면 데이터가 조용히 사라지기 때문에, 이 동작을 직접 확인해 두는 것이 중요하다. 이 노트에서는 딕셔너리 컴프리헨션의 기본 문법과 중복 키에서 마지막 값이 남는 이유, 그리고 그 동작을 확인하는 방법을 정리해 본다.개념 설명딕셔너리 컴프리헨션은 리스트 컴프리헨션과 같은 형태로 쓴다. 중괄호 안에 키표현식: 값표현식 f..
Python 함수 정의와 리스트 순회 기본 예제 정리
·
Python
왜 이 내용을 정리하나파이썬으로 데이터를 다룰 때 가장 자주 쓰는 패턴은 리스트를 받아 조건에 맞는 값만 골라 가공하는 것이다. 숫자 목록에서 짝수만 뽑거나, 문자열 목록에서 특정 글자로 시작하는 항목만 모으는 작업이 대표적이다. 이런 작업은 함수로 감싸 두면 호출하는 쪽에서 입력과 출력만 신경 쓰면 되므로 코드가 읽기 쉬워진다. 그래서 함수를 정의하는 문법과 for 문으로 리스트를 순회하는 방식을 함께 익혀 두면 이후의 여러 예제를 이해하는 데 도움이 된다. 이 노트에서는 함수 정의, 리스트 순회, 조건문, 리스트에 값을 쌓는 방법을 짧은 예제 하나로 묶어서 정리해 본다.개념 설명파이썬에서 함수는 def 키워드로 정의한다. def 다음에 함수 이름과 괄호 안의 매개변수 목록을 쓰고, 콜론 뒤에 들여쓰기..
파이썬 제너레이터와 yield로 대용량 파일을 메모리 효율적으로 읽기
·
Python
왜 이 내용을 정리하나파이썬으로 로그 파일이나 CSV 파일을 처리하다 보면, 파일 크기가 수 GB를 넘는 경우를 자주 만난다. 이런 파일을 read()로 통째로 읽으면 전체 내용이 메모리에 올라가서 프로그램이 느려지거나 메모리 부족 오류가 날 수 있다. 그래서 파일을 한 줄씩 읽으면서 필요한 만큼만 메모리에 두는 방법이 필요하다. 이 노트에서는 제너레이터와 yield가 이 문제에 어떻게 쓰이는지 정리해 본다.개념 설명제너레이터(generator)는 값을 한꺼번에 만들어 리스트에 담아 두지 않고, 요청될 때마다 하나씩 만들어 내는 이터레이터이다. 함수 안에서 yield 키워드를 쓰면 그 함수는 일반 함수가 아니라 제너레이터 함수가 된다. yield는 값을 호출한 쪽에 돌려주고 함수의 실행 상태를 그대로 멈..