프로그래머스 파이썬 기초 트레이닝 :: in / not in 문제 모음

     





    문제들 

    Day-11  (3) 글자 지우기




    문제 이해

    리스트에서 요소를 삭제할때, 4가지 방법이 있다.

    del list[idx], list.remove(value), list.pop(idx), 인덱스 슬라이싱을 사용할 수 있다. 

    하지만, del 함수, remove 메서드, pop 메서드를 사용하면 삭제된 만큼 리스트의 인덱스가 변해서 for문에서 사용할때 원하는 결과값을 얻지 못할 수도 있다. 

    그래서 나는, 지우고자하는 값을 공백으로 바꿔서 인덱스를 유지하는 방법을 선택했는데, in / not in 멤버 연산자를 활용해서 쉽게 푸는게 가능하다. 


    프로그래머스 기초 트레이닝 문제 중에서 not in / in 연산자로 해결하는 문제들을 한번에 정리해 보았다. 



    멤버 연산자 형태

    value not in group 

    value in group 




    ------------------------------------------------


    (in연산자랑 리스트의 활용도 유용하게 쓰여서, 추가함)

    if 조건문에서 today == 'a' or today == 'b' 처럼 값을 체크하는 경우를 in + list를 쓸수있다.

    ### 1. 처음에 한 코드 - '=='로 하나씩 체크
    today = input('요일을 입력하세요(월, 화, 수, 목, 금, 토, 일) : ')
    if today == '토' or today == '일' :
      for k, v in icecream.items() :
        print(f'아이스크림 이름: {k} => 할인가: {v[1]}')


    if today in ['a' , 'b'] 이 가능하다 ! 

    ### 2. 리스트 형태랑 in 연산자 써서 한번에 체크 
    today = input('요일을 입력하세요(월, 화, 수, 목, 금, 토, 일) : ')
    if today in ['토', '일'] :
      for k, v in icecream.items() :
        print(f'아이스크림 이름: {k} => 할인가: {v[1]}')





    ------------------------------------------------



    Day-11 (3) 글자 지우기 


    코드 1 

    내가 처음에 푼 방식 : 공백 처리

    def solution(my_string, indices):
        l = list(my_string)
        for i in indices : 
            l[i] = ''
        return ''.join(l)


    for 문 안에서, list.remove(value), list.pop(idx), del list(idx) 사용하니까

    인덱스가 줄어들어서 삭제하는 방법말고, 공백으로 대체하는 방식으로 풀었다. 


    하지만, 이 방식보다 더 좋은 방법이 not in / in 멤버 연산자를 활용하는 것이었다. 

    "indices 리스트에 해당되는 값을 제거한다" 라는 말은 

    "indices 리스트에 해당되지 않는 값은 가진다 " 라는 말과 같다.

    그래서, 제거를 하지 않고, not in 연산자를 활용해 해당되지 않는 값만 저장하면 된다



    코드 2 

    문자열에 저장

    def solution(my_string, indices):
        answer = ''
        for i in range(len(my_string)):
            if i not in indices:
                answer+=my_string[i]
        return answer


    indices 에 해당하지 않는 값을 문자열 변수에 추가하는 코드이다. 

    문자열에 값을 저장하는 방식인데, 문자열(str) 타입은 값이 변하지 않는 특성을 가진다. 

    answer += my_string[i] 으로 문자열을 합칠때 마다, 수정이 되는게 아니라, 새로운 문자열이 생성되기 때문에 시간 복잡도 측면에서 봤을때 리스트보다 오래 걸린다고 볼 수 있다. 


    리스트는 값이 변하는 특성을 가지고 있기때문에, 시간 복잡도 측면에서 문자열 보다 낫다고 볼 수 있다. 


    코드 3 

    리스트에 저장
    def solution(my_string, indices):
        answer = []
        for i in range(len(my_string)) :
            if i not in indices :
                answer.append(my_string[i])
        return ''.join(answer)    

    리스트에 값을 저장하는 방식이고, 마지막에 join 함수로 문자열을 반환하는 코드이다. 

    not in 연산자로 값을 거르는 방식은 코드 2 방식과 완전히 일치 


    def solution(my_string, indices):
        return  ''.join(my_string[i] for i in range(len(my_string)) if i not in indices)          

    리스트 컴프리헨션으로 한 줄 코드도 가능하다. 




    ------------------------------------------------



    Day-15 (3) 원하는 문자열 찾기



    코드 1

    내가 푼 방법 : if 문
    def solution(myString, pat):
        if pat.lower() in myString.lower() : return 1
        else : return 0


    위의 코드를 한줄 if문으로 간결하게 쓰면 아래와 같다. 

    내가 푼 방법 2 : 한줄 if문  

    def solution(myString, pat):
        return (1 if pat.lower() in myString.lower() else 0)


    이렇게 단순 1, 0 으로 되는건 int 형변환으로 boolean 값을 활용할 수 있다. 

    코드 2 

    def solution(myString, pat):
        return int(pat.lower() in myString.lower())



    ------------------------------------------------


     


    Day-17 (3) 원하는 문자열 찾기



    코드

    def solution(strArr):
        answer = [] 
        for i in strArr:
            if "ad" not in i : 
                answer.append(i)
        return answer


    위의 코드를 리스트 컴프리헨션으로 간결하게 쓰면 아래와 같다. 

    def solution(strArr):
        return [i for i in strArr if 'ad' not in i]




    ------------------------------------------------


    Day-19 (5) 무작위로 k개의 수 뽑기



    코드 1

    내가 푼 방법

    def solution(arr, k):
        answer = []
        for i in arr : 
            if i not in answer and len(answer) != k  :
                answer.append(i)
        if len(answer) < k :
            for i in range(k - len(answer)) : 
                answer.append(-1)
        return answer 


    개선할 점 - 단순한건 for문 대신 * 연산으로

    for i in range(k - len(answer)) :
        answer.append(-1)

    부족한 만큼 -1 을 채우는걸 for문으로 실행을 시켰다.

    하지만, 굳이 for문을 안쓰고 *연산으로도 가능

    answer += [-1] * (k - len(answer)) 



    코드 2 

    비슷한데 살짝 다른 코드  

    def solution(arr, k):
        ret = []
        for i in arr:
            if i not in ret:
                ret.append(i)
            if len(ret) == k:
                return ret
        return ret + [-1] * (k - len(ret))

    if문을 안에 둬서, 배열 길이가 k랑 같은지를 체크한다. 

    그러고 나서, 부족한 배열 길이만큼 -1로 채움



    코드 3

    set을 리스트화 해서 활용 

    def solution(arr, k):
        s = list(set(arr))
        if k < len(s) : return s[:k]    
        elif k == len(s) : return s 
        else : return s[:] + [-1 for i in range(k-len(s))]

    set 타입은 순서가 없는 특징을 가지고 있기때문에 list 형변환을 해줘야지 인덱스 접근이 가능하다. 




    ------------------------------------------------

     

    Day-22 (4) 배열의 원소 삭제하기





    코드 1

    내가 푼 방법 : list.remove(value) 사용하기 

    def solution(arr, delete_list):
        for d in delete_list :
            if d in arr :
                arr.remove(d)
        return arr 

    리스트 요소를 삭제하는 remove 메서드를 사용했다. 

    이를 짧게 만들면 아래와 같다.

    def solution(arr, delete_list):
        [arr.remove(d) for d in delete_list if d in arr]
        return arr
    리스트 삭제 메서드는 remove, del, pop 으로 할 수 있는데 

    remove만 매개변수가 value 값이라 인덱스를 몰라도 삭제할 수 있다.

    반면에 del, pop은 매개변수가 index 라서 값을 모르고 인덱스 값만 알때 사용 가능 



    코드 2 

    not in 연산자 사용해서 새로운 list에 저장   

    def solution(arr, delete_list):
        answer = []
        for a in arr : 
            if a not in delete_list : 
                answer.append(a)
        return answer

    코드1은 기존의 리스트에서, 요소 값을 지웠다면

    코드2는 원하는 값만 받아서 새로운 리스트에 저장하는 방법 

     

    코드를 짧게 바꾸면 ↓

    def solution(arr, delete_list):
        return [a for a in arr if a not in delete_list]



    코드 3

    set을 리스트화 해서 활용 

    def solution(arr, k):
        s = list(set(arr))
        if k < len(s) : return s[:k]    
        elif k == len(s) : return s 
        else : return s[:] + [-1 for i in range(k-len(s))]

    set 타입은 순서가 없는 특징을 가지고 있기때문에 list 형변환을 해줘야지 인덱스 접근이 가능하다. 



    ------------------------------------------------

     


    Day-22 (5) 부분 문자열인지 확인하기




    코드 

    내가 푼 방법 

    def solution(my_string, target):
        if target in my_string :
            return 1 
        else : 
            return 0 


    이를 짧게 만들면 아래와 같다.

    def solution(my_string, target):
        return (1 if target in my_string else 0 )


    int 형변환을 사용해서, 더 간결하게 만들수 있다.    

    def solution(my_string, target):
        return int(target in my_string)





    ------------------------------------------------

     


    Day-23 (2) 꼬리 문자열





    코드 1

    내가 푼 방법 : 공백으로 대체 

    def solution(str_list, ex):
        for i in range(len(str_list)) : 
            if ex in str_list[i] :
                str_list[i] = ''
        return ''.join(str_list)

    리스트 요소를 삭제하는 메서드나 함수를 for 문 안에서 쓰면 인덱스가 꼬여서 원하는 기댓값을 얻을 수 없다. 

    그래서 공백으로 대체해서 풀었다. 


    코드 2

    not in 멤버 연산자  

    def solution(str_list, ex):
        answer = []
        for i in str_list : 
            if ex not in i :
                answer.append(i)
        return ''.join(answer)


    간결하게 쓰면 아래와 같음

    def solution(str_list, ex):
        return ''.join([i for i in str_list if ex not in i])



    코드 3 

    if문 대신에 filter 함수를 사용   

    def solution(str_list, ex):
        return ''.join(filter(lambda x: ex not in x, str_list))






    댓글

    이 블로그의 인기 게시물

    [KT 에이블스쿨 - IT 트랜드] 국내외 AI 관련 규제

    KT 에이블스쿨 : IT 인프라 (1일차~5일차) 공부 정리

    KT 에이블스쿨 : 핀테크 아이디어 공모전