python을 시작하기 전에
python 얘기를 시작하기전에 우선 나는 python을 싫어했다.
나는 데이터 분석 업무를 맞고 있는 1년차 직장인이다.
나는 대학교 2학년 때부터 AI 업무를 진행하였다. 그 때 접하게 된 프로그래밍 언어는 R이였다.
이렇게 R언어는 내 분석업무에 주가 되주는 언어가 되었다.
하지만 취업의 문 앞에서 python을 선택할 수 밖에 없었다.
취업 당시 R은 통계분석에서는 python보다 강력했으나, 웹 기반 서비스인 shiny는 Django나 Flask 대비 무거웠고,
딥러닝쪽에서 조차 힘을 쓰지 못하였었다.
내가 싫어했던 이유는 사실 프로그래밍언어가 어려워서가 아니였던 것 같다.
자유도 측면에서 python은 거부감이 많이 들었던 것 같다.
파이썬은 개발을 고려한 프로그래밍이라 묵시적인 코딩 규칙들이 있었고,
나는 비전공자라 이러한 코딩 규칙은 전혀 무지하였다.
또한 여러가지 분석가가 몰라도 되는 애러 이슈들이 많이 있다.
이외에도 많은 말도안되는 이슈들이 존재한다. 하지만 오늘은 한 블로그에 정리된 문제점을 소개하고자 한다.
github.com/pablogsal/python-horror-show
해당 블로그에서는 1. python의 정수 객체 처리 문제 2. 메모리 스왑 문제 3. 무한 반복 생성 4. Hashable Object 문제
5. Iterator 관련 문제 6. 논리 우선순위 문제 7. 객체 변환 문제 등이 있다.
Python의 정수 객체 처리
python은 -5 ~ 256까지의 정수 객체 생성에서는 기존 생성된 메모리를 공유한다.
그래서 객체를 생성할 때 매번 다른 메모리에 재할당 되는데 -5~256은 같은 결과가 나타난다.
메모리 스왑
python의 메모리 스왑 기능은 매우 강력하므로 많이들 사용한다.
하지만 아래와 같이 a, b=b, a format은 안되는데 a=b는 적용이 되는 아이러니한 현상이 나타난다.
* python의 index 함수는 리스트 내에서 특정 값의 위치를 찾아주는 함수이다.
우리는 이러한 현상을 이해하려면 a, b= b, a의 적용 순서를 알아야 한다.
a[a.index(1)], a[a.index(2)]= 2, 1은 다음과 같이 기작한다.
index함수는 중복값이 있을 때 맨 처음 나타나는 값만을 return해준다.
따라서 함수가 적용되지 않은게 아니라 같은 값이 있을 때 index함수가 맨 처음 위치값을 반환하므로,
결과값이 안바뀐 경우라 할 수 있다.
그래서 입력값이 다른 경우에는 문제없이 적용이 된다.
무한 반복 생성
나는 다중 할당 정도로 생각을 하고 있었는데 propositional logic implications of the statement라고 문법이 있나보다.
집합론 관련 논리 내용 같은데 주제와 벗어나는 것 같기도 하고 잘 쓸 자신이 없어서 생략한다.
하지만 다중 할당의 순서는 알아두면 좋을 것 같다.
a, b={}, 5로 할 당하고(P) a[b]를 {}, 5로 할당(Q)하는 결과를 얻고 싶어한다.
a = b = c 의 형태의 문법은 생각에 왼쪽에서 오른쪽으로 가거나 a=c & b=c형태로 진행 되어야 할 것이라 생각했다.
저자는 a=c & b=c를 원했던 것 같다. 우선 아래는 결과다.
왜 저렇게 무한 반복이 될까??
예상과는 다르게 코드는 위와 같이 진행이 되었다.
원했던 결과를 얻으려면 아래와 같이 결국 문법을 나누어 제시하여야 한다.
Hashable Object 문제
나도 hashable object가 뭔지 잘 몰랐다. 그래서 검색해보니 hash함수에 인자로 들어갈 수 있는 객체들을 의미한다.
대충 hash에 object로 올 수 있는 값들은 변경 불가능 한 값들이어야 한다.
즉, int, bool, float, tuple, string, bytes 등은 hash에 object로 올 수 있는 반면,
list, dict, set 등은 hash에 object로 올 수 없다.
이 얘기를 왜하냐면..
우리는 dictionary의 key 값으로 unique한 값을 필요로 한다.
근데 보다시피 따로는 정수 1도, True 값도, 1.0도 key값으로 올 수 있다. 어찌보면 당연하다.
근데 죄다 어디로 사라지는지 모르겠다.
hash 값을 확인해 본 결과 모두 1값을 가졌다. 그래서 덮어써진 것 같다.
또한 hash 값이 같아서 ==연산자 결과가 같은 것을 볼 수 있다.
공집합은 모든집합의 부분집합이므로 False
all 함수는 object 내에 논리기호 모두 True 값을가져야 True를 반환 아니면, False를 반환하는 함수
수학적으로 왜 공집합이 False인지는 아직 이해가 가지는 않는데.. 일단 그래서 코드를 보기로 했다.
파이썬 공식 문서는 위와 같이 나타났다.
만약 입력자료 중 하나라도 not 연산을 했을 때 True가 되면(하나라도 False이면) False를 반환 아니면 True를 반환
공집합은 for문 자체가 실행이 안되므로, 그냥 True를 반환한다.
공집합은 논리상으로 False를 의미한다.
따라서
all([])이 True였음에도 불구하고, [[]]는 [True]와 같음에도 False라는 이상한 결과가 나타난다.
이는 아래와 같이 코드가 돌기 때문이다.
이터레이터 관련 이슈
해당 이슈는 완전히 이해가 가지 않았으나, 사용도가 높지 않을 것 같아 결과만 첨부하였다.
sorted함수는 list를 반환하는데 reversed 함수는 iterator를 반환한다고 한다고 합니다.
reversed 함수는첫번째 호출에서 sorted함수를 호출한다고 합니다. 따라서 다음과 같이 공집합을 반환한다고 합니다.
논리 우선순위 문제
앞서 무한 반복 생성에서 봤듯이 python은 논리를 처리할 때 a == b in c이 있다고하면,
앞에서부터 연산을 하는게 아니라 a in c , b in c를 구한뒤 그 결과값이 a' , b' 이라고 하면 a'==b'을 진행하는 것 같다.
수학과 입장으로 참으로 마음에 안드는 결과가 아닐 수 없다.
객체 변환 문제
float과 int에 따른 논리 결과가 다른 문제를 보여준다.
본문에서 x<<y라는 operator가 있다.
이 operator는 비트가 y자리만큼 왼쪽으로 이동한 x를 반환한다는데 잘 모르겠다.
이것은 x에 2 ** y를 곱하는 것과 같은 결과라고 한다. 알고자 하는 결과와는 무관하니 넘어가자..
위와 같은 결과가 나오는 이유는
int와 float은 변환 과정에서 가까운 값으로 반올림하는 과정이 있다고 한다.
int가 float 변환 과정에서 원래 값으로 변환이 된다고 하고,
float값에서 1을 더해줘서 원래 값이 나와야 하는데 뭐 반올림 과정에서 그대로 나타난다고 한다.
문제점을 알고 사용할수록 예기치 못한 에러를 이해하기 쉽다고 생각한다.
도움이 되기를 바란다.
'python' 카테고리의 다른 글
코딩 스타일과 관리 (0) | 2021.02.28 |
---|---|
jupyter kernel 제대로 추가 안될 때 (2) | 2021.01.24 |
python oracle DB 연동 (0) | 2020.12.03 |
offline conda pack spyder설치 에러 (0) | 2020.12.01 |
conda python 경로 인식못할 때 (0) | 2020.11.28 |