본문 바로가기

Study

[파이썬 알고리즘 인터뷰] 2부. 파이썬(中 4장 자료형, 5장 리스트/딕셔너리, 6장 문자열 조작)

본 글은 저자 박상길 님의 '파이썬 알고리즘 인터뷰'를 읽은 후 작성한 것임을 사전에 밝힙니다.
전체 글을 모두 요약하기보다는 데이터분석가로서 필요한 내용 위주로 기록한 내용입니다.

[이전글 참고] 2021/02/10 - [Study] - [파이썬 알고리즘 인터뷰] 1부. 코딩 인터뷰 및 2부. 파이썬(中 3장 파이썬)

 

[파이썬 알고리즘 인터뷰] 1부. 코딩 인터뷰 및 2부. 파이썬(中 3장 파이썬)

본 글은 저자 박상길 님의 '파이썬 알고리즘 인터뷰'를 읽은 후 작성한 것임을 사전에 밝힙니다. 전체 글을 모두 요약하기보다는 데이터분석가로서 필요한 내용 위주로 기록한 내용입니다. [1부.

yunni92.tistory.com

[2부. 파이썬]

 

20210131_파이썬알고리즘인터뷰_2부_파이썬_4,5,6장

4장. 자료형

  • 코딩테스트에서도 가장 많이 출제되는 List 와 Dictionary 위주로 설명

-파이썬에서의 자료형

In [57]:
from IPython.display import Image
Image("/Users/mac/Downloads/nhuQL0XpWlXASOrt8nAM.jpg")
Out[57]:

[출처] 파이썬알고리즘 인터뷰(저자 박상길)

숫자형

  • PEP 237을 통해 파이썬 버전 2.4부터는 int, long --> int 만 사용
  • int가 넘치면 자동으로 long으로 변환
  • Object > int > bool
In [44]:
# 논리자료형(bool)은 내부적으로 정수값
print(True==1)
print(False==0)
True
True

매핑형

  • 키와 자료형으로 구성된 복합 자료
  • 파이썬에 내장된 유일한 매핑 자료형은 바로 'dictionary'

집합형

  • 'set'은 중복된 값을 갖지 않는 자료형
In [50]:
# 중복 무시
a={'a', 'a', 'b', 'c'}
print(type(a))
a
<class 'set'>
Out[50]:
{'a', 'b', 'c'}
In [47]:
# set도 dictionary와 동일하게 중괄호({})를 사용하므로 이점에 유의해야 함
# value만 나열하면 set, key:value 형태로 나열하면 dictionary 
a={'a', 'b', 'c'}
print(type(a))
b={'a':'A', 'b':'B', 'c':'C'}
print(type(b))
<class 'set'>
<class 'dict'>

시퀀스

  • 불변(immutable) 시퀀스: 'str', 'tuple', 'bytes'
  • 가변(mutable) 시퀀스: 'list'
In [60]:
# 다음은 값이 변경되는 것이 아닌 '참조값'이 변경되는 경우이다.
a='abc'
print(a, id(a))
a='def'
print(a, id(a))
abc 140318679245552
def 140318681468784
In [62]:
# 'str' 타입이 불변인 이유
print(a)
print(a[1])
a[1]='a'
def
e
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-62-7448876d9540> in <module>
      2 print(a)
      3 print(a[1])
----> 4 a[1]='a'

TypeError: 'str' object does not support item assignment
In [64]:
# 여러 객체들 중 'list', 'set', 'dictionary는' 가변!
# b값에 주목!!
a=[1,2,3,4,5]
b=a
a[1]=4
print(a)
print(b)
[1, 4, 3, 4, 5]
[1, 4, 3, 4, 5]

is 와 == 의 차이

  • is: id() 값을 비교하는 함수
  • ==: 값을 비교하는 함수
In [72]:
# None, null, nan은 값 자체가 정의되어 있지 않으므로 == 로 비교가 불가능
# 따라서 is 로만 비교가 가능함
import numpy as np
a= np.nan
if a == np.nan:
    print('a == nan')
if a is np.nan:
    print('a is nan')
a is nan
In [82]:
# list를 다시 list화 시키면 별도의 객체가 생성되고 다른 ID를 갖게됨
# 따라서 == 로만 비교가 가능함
a=[1,2,3]
b=list(a)
print('a==b ?: ', a == b)
print('a is b ?: ', a is b)
a==b ?:  True
a is b ?:  False

5장. 리스트, 딕셔너리

  • 파이썬에서 가장 빈번하게 접하게 되는 자료형일것

-List

  • 순서대로 저장하는 시퀀스이자 변경 가능한(Mutable) 목록
  • Stack 과 Que에서 가능한 모든 연산을 제공

기본적인 활용

In [153]:
# 리스트 선언
a=list()
a=[]
In [227]:
# 원소 추가 
a=[1,2,3]
a.append(4)
a
Out[227]:
[1, 2, 3, 4]
In [228]:
# (필요한 위치에) 원소 추가

# a 리스트의 3번째 index에 5를 추가
a.insert(3,5)
a
Out[228]:
[1, 2, 3, 5, 4]
In [229]:
# 인덱스를 이용하여 원소 찾기

# 1이상 4미만을 2씩 띄어서
a[1:4:2]
Out[229]:
[2, 5]
In [237]:
# 뒤에서1(4)이상 1미만을 거꾸로 2씩 띄어서
a[-1:1:-2]
Out[237]:
[4, 3]
In [161]:
# 원소 삭제 -인덱스로 삭제 (del 이용)
a=[1, 2, 3, 5, 4]
del a[1]
a
Out[161]:
[1, 3, 5, 4]
In [ ]:
# 원소 삭제 -인덱스로 삭제 (pop 이용)
a=[1, 2, 3, 5, 4]
# 삭제될 값을 리턴하고 실제 list에도 삭제가 진행함
print(a.pop(3))
a
In [163]:
# 원소 삭제 -값으로 삭제 (remove(값) 이용)
a=[1, 2, 3, 5, 4]
a.remove(3)
a
Out[163]:
[1, 2, 5, 4]

-Dictionary

  • 키/값 구조로 이루어진 구조
  • 최근(Python ver 3.7~) 입력된 순서가 유지 되도록 변경되었지만, 3.6 이하 버전과의 호환성을 위하여 순서가 유지되지 않는다고 가정하는것을 추천

기본적인 활용

In [167]:
# 딕셔너리 선언
a=dict()
a={}
In [168]:
# 선언된 딕셔너리에 '키', '값' 할당
a['key']='value'
a
Out[168]:
{'key': 'value'}
In [170]:
# 딕셔너리의 키/값은 for문에 items()함수를 이용하여 조회 가능
for k,v in a.items():
    print(k,v)
key value
In [171]:
# 원소 삭제 -키로 삭제(del 이용)
del a['key']
a
Out[171]:
{}

딕셔너리의 모듈들

  • defaultdic, Counter, OrderDict
In [179]:
# defaultdic: 존재하지 않는 키를 조회할때 에러메시지를 출력하는 대신 디폴트값을 기준으로 해당 키에 딕셔너리 아이템 생성해줌

# 기본 딕셔너리는 아래 과정에서 에러메시지 출력
a=dict()
a['A']+=1
a
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-179-e806f44aab6d> in <module>
      3 # 기본 딕셔너리는 에러메시지 출력
      4 a=dict()
----> 5 a['A']+=1
      6 a

KeyError: 'A'
In [180]:
import collections
a=collections.defaultdict(int)
a['A']+=1
a
Out[180]:
defaultdict(int, {'A': 1})
In [196]:
# Counter: list의 아이템 개수를 계산하여 딕셔너리 형태로 리턴
a=[1,2,3,4,5,5,5,6,6,7,7,7]
b=collections.Counter(a)
print(b)
type(b)
Counter({5: 3, 7: 3, 6: 2, 1: 1, 2: 1, 3: 1, 4: 1})
Out[196]:
collections.Counter
In [205]:
# 빈도수를 기준으로 정렬
print(b.most_common())
# 빈도수가 높은 2개의 값을 (값, 빈도수) 형태로 보여줌 
print(b.most_common(2))
# 빈도수가 낮은 2개의 값을 (값, 빈도수) 형태로 보여줌 
print(b.most_common()[-2:])
[(5, 3), (7, 3), (6, 2), (1, 1), (2, 1), (3, 1), (4, 1)]
[(5, 3), (7, 3)]
[(3, 1), (4, 1)]
In [208]:
# OrderedDict: 버전 3.6 이하에서 입력순서 유지를 위하여 사용
a=collections.OrderedDict({'banana':3, 'apple':2, 'pear':1})
a
Out[208]:
OrderedDict([('banana', 3), ('apple', 2), ('pear', 1)])

6장. 문자열 조작

-팰린드롬 여부 판별

  • Palindrome 이란 앞뒤가 똑같은 문자열을 말함
In [238]:
# 슬라이싱 사용한 풀이
import re 

def isPalindrome(s: str)->bool:
    s=s.lower()
    # 정규식으로 불필요한 문자 필터링 
    s=re.sub('[^a-z0-9]','',s)
    
    return s==s[::-1]

isPalindrome('A man, a plan, a canal: Panama')
Out[238]:
True

-문자열 뒤집기

In [269]:
def reverse_string(s:str):
    a=list(s)
    a.reverse()
    return ''.join(a)

reverse_string('apple')
Out[269]:
'elppa'

-가장 흔한 단어

In [271]:
def most_common_word(paragraph:str, banned:[str])->str:
    words=[word for word in re.sub(r'[^\w]', ' ', paragraph)
          .lower().split()
          if word not in banned]
    counts=collections.Counter(words)
    return counts.most_common(1)[0][0]

paragraph="Bob hit a ball, the hit BALL flew far after it was hit."
banned=["hit"]

most_common_word(paragraph,banned)
Out[271]:
'ball'

-여러가지 정렬 방법

In [273]:
# sorted(a): 문자/리스트 정렬 -> 리스트 형태 반환
a='dbca'
print(sorted(a))
a=['다','나','가','마']
print(sorted(a))
['a', 'b', 'c', 'd']
['가', '나', '다', '마']
In [274]:
# sorted(a) 를 이용하여 문자열 형태로 반환 
a='dbca'
"".join(sorted(a))
Out[274]:
'abcd'
In [276]:
# a.sort(): 리스트를 제자리 정렬(In-place Sort), 즉 입력을 출력으로 덮어 쓰기때문에 별도의 추가 공간이 필요하지 않고 리턴값이 없음
a=['다','나','가','마']
a.sort()
a
Out[276]:
['가', '나', '다', '마']
In [277]:
# 잘못된 구문: In-place 함수는 아무 리턴값이 없음
a=['다','나','가','마']
result=a.sort()
result
In [282]:
# sorted(a, key=len): 알파벳 순서가 아닌 문자열의 길이를 이용하여 정렬
sorted(['aaa', 'bbab', 'cda', 'bbba'], key=len)
Out[282]:
['aaa', 'cda', 'bbab', 'bbba']
In [284]:
# key에 다양한 함수를 이용하여 만들 수 있음

# 1순위. 문자열 첫번째와 2순위. 마지막 문자를 이용
sorted(['aaa', 'bbab', 'cda', 'bbba'], key=lambda s:(s[0], s[-1]))
Out[284]:
['aaa', 'bbba', 'bbab', 'cda']

[참고] Python's PEP 8, Google's python style guide