프로그래머스 파이썬 기초 트레이닝 :: 배열 만들기 2 (all, set, filter, in, 집합연산자 *)

            

    문제 설명 

    프로그래머스 URL

    https://school.programmers.co.kr/learn/courses/30/lessons/181921



    프로그래머스 코딩 카테고리 

    코딩 기초 트레이닝

    Day 7 반복문 - 배열 만들기 2

    Lv.0





    문제 내용 

    정수 l과 r이 주어졌을 때, l 이상 r이하의 정수 중에서 숫자 "0"과 "5"로만 이루어진 모든 정수를 오름차순으로 저장한 배열을 return 하는 solution 함수를 완성해 주세요.

    만약 그러한 정수가 없다면, -1이 담긴 배열을 return 합니다.



    l         r         result
    5         555         [5, 50, 55, 500, 505, 550, 555]
    10         20         [-1]




    제한 사항

    1 ≤ l ≤ r ≤ 1,000,000




    문제 이해

    [입력] l 정수, r 정수

    [출력] 리스트, 비었으면 -1 

    1. l부터 r까지 정수 (반복문) 

    2. 각 정수가 0, 5로 이뤄졌는지 확인 (if문) 

    3. 조건 만족하면 해당 정수 리스트에 저장 (if - 실행문)

    4. 최종 리스트을 오름차순으로 정렬 (sort, sorted, reverse, [ : : -1]) 

    5. 리스트 반환, 리스트가 비었으면 -1 




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


    [ all 함수 + 멤버 연산자 ] 활용하는 경우

    정답 코드

    def solution(l, r):
        result = []
    
        for num in range(l, r+1):
            if all(digit in "05" for digit in str(num)):  #in {'0', '5'}
                result.append(num)
        return sorted(result if result else [-1])
    

    if 조건문에 all 함수를 사용하고, l ~ r 사이의 숫자를 문자열 num 으로 받아서 0, 5 값을 포함하는지 검사하는 코드이다. 

    이 조건문에서 사용한 all 함수랑, in "05" 는 무엇이고, 왜 num을 문자열로 받았는지를 정리해볼려고 한다. 



    ① all 함수

    파이썬 내장함수

    인자로 받은 iterable 의 모든 요소가 참인지를 검사하는 함수이다. 모든(all) 요소가 참이여야 참(True)를 반환한다.


    문법 : 변수 = all (iterable) 

    all 함수 구현코드 (파이썬 공홈)  

    def all(iterable):
        for element in iterable:
            if not element:
                return False
        return True

    all 매개변수로 들어온 iterable을 for문 돌려서, 하나라도 if not element 조건에 걸리면 False를 반환한다. 


    예시  (코드 출처)

    # 리스트
    a = [1,2,3,4,5]
    result = all(a)
    print(f'all([1,2,3,4,5]) : {result}')  #True
    
    
    # 리스트가 비어있는 경우
    c = []
    print(f'all([]) : {all(c)}')  #True
    
    
    # 문자열
    d = 'BlockDMask'
    print(f'all(\'BlockDMask\') : {all(d)}')    #True
    
    
    # 비어있는 문자열
    e = ''
    print(f'all(\'\') : {all(e)}')  #True
    
     
    # 튜플
    f = ('b', 3, 'a')
    print(f"all(('b', 3, 'a')) : {all(f)}")   #True
    
    
    # 비어있는 튜플
    i = ()
    print(f"all(()) : {all(i)}")   #True

    비어있는 튜플, 리스트 자체도 True 로 반환 


    # 리스트 요소에 0 -> False 이 있는 경우
    b = [1,2,0,4,5]
    print(f'all([1,2,0,4,5]) : {all(b)}')  #False
    
    
    # 0이 있는 튜플
    g = ('b', 2, 0, 'd')
    print(f"all(('b', 2, 0, 'd')) : {all(g)}")  #False 
    
    
    # 빈 문자열이 있는 튜플
    h = ('a', '', 2, 3)
    print(f"all(('a', '', 2, 3)) : {all(h)}")  #False 
    요소 중에 빈 문자열이 있거나, 숫자 0 이 있으면 False를 반환한다. 


    위의 코드처럼 iterable에 리스트, 튜플이 들어간 경우가 아닌

    for문, and 연산자, or연산자, in 멤버 연산자를 넣을 수 있다. 

    # 숫자 범위의 모든 요소가 참이므로 True 반환
    result = all(x > 0 for x in range(1, 6))
    print(result)  # 출력: True
    
    
    # 문자열의 모든 문자가 알파벳인 경우 True 반환
    result = all(c.isalpha() for c in 'Hello')
    print(result)  # 출력: True
    
    
    # 문자열의 모든 문자가 숫자인 경우 False 반환
    text = "Hello123"
    result = all(c.isdigit() for c in text)
    print(result)  # 출력: False
    
    
    # 리스트의 모든 요소가 양수이고 짝수인 경우 True, 아닌 경우 False 반환
    numbers = [2, 4, 6, 8, 10]
    result = all(num > 0 and num % 2 == 0 for num in numbers)
    print(result)  # 출력: True


    ② in 멤버 연산자

    멤버 연산자는 in / not in 두개가 있다. 어떠한 값이 포함되어 있는지의 여부를 판단 

    value in group : 값을 포함하는지 검사

    value not in group : 값이 포함되어 있지 않은지 검사

    ※ 주의 : 여기서 group 은 sequence를 가진 리스트, 튜플, 문자열 그리고 set 이 올수있음


    예시

    members = ['초롱', '아름', '별님' ]
    print('O' if '아름' in members else 'X')

    문자열 in 리스트 형식으로 사용을 했다. 

    이처럼, in 뒤에오는 자리에는 리스트, 튜플, 문자열, set 만 올수있다. 

    만약 숫자를 넣으면 iterable이 아니라서 오류가 발생한다. 

    if all(digit in "05" for digit in str(num)): 
    if all(digit in {'0', '5'} for digit in str(num)) : 

    0, 5를 포함하는 값을 구할려는 이 코드에서 in 뒤에는 iterable이 와야하기 때문에,

    in 05은 불가능하고 

    in "05" 또는 in {'0', '5'} 로 사용을 해야한다. 





    [ set() ] 활용하는 경우

    정답 코드

    def solution(l, r):
        answer = []
        for num in range(l, r + 1):
            if not set(str(num)) - set(['0', '5']):
                answer.append(num)
        return answer if answer else [-1]
    

    주어진 범위 내에서 숫자를 문자열로 변환하고,

    이 문자열의 각 자릿수를 집합으로 만든 후, 

    이 집합에서 {'0', '5'}를 뺀 결과가 빈 집합인 경우에 해당 숫자를 결과 배열에 추가

    (set(str(num)) - set(['0', '5'])이 빈 집합이라면, 해당 숫자는 '0'과 '5'로만 이루어져 있으므로)


    집합을 - 연산으로 값의 포함 여부를 확인할 수 있는 방식이 신선했다. 

    105 숫자로 이뤄진 num를 str형변환하고, set(str(num)) 하면 최종적으로 {'1', '0', '5'} 이렇게 생성이 될 것이다. 

    이 값을 set(['0', '5']) 또는 { '0', '5' }이랑 확인하는 것


    문자열로 형변환하는 이유 

    num을 문자열로 형변환하지 않고, 숫자 리스트 자체를 넣으면 아래 코드와 같다. 

    if not set([num]) - {0, 5}:
        answer.append(num)
    실행한 결괏값 [5]이 기댓값 [5,50,55,500,505,550,555]과 다릅니다.

    set([num])처럼 숫자 자체만으로 set을 씌우면, 105 단일값으로 {105} 이렇게 되기때문에 기댓값과 달라진다. 




    [ filter함수 + 부분집합 연산자 ] 활용

    정답 코드

    def solution(l, r):
        result = sorted(filter(lambda x: set(str(x)) <= {'0', '5'}, range(l, r+1)))
        return result if result else [-1]
    

    filter 함수의 첫번째 매개변수에 lambda를 쓰고, 두번째는 range 함수를 써서 iterable을 표현했다. 

    filter 함수랑, <= 연산자가 무엇인지 잘 몰라서 정리를 해봤다. 


    ① filter 함수

    이 문제에서 in 부분 연산자, set() - set() 과 같은 기능을 기능을 하는 파이썬 내장함수이다. 


    목적 iterable에서 특정 조건을 만족하는 요소들만을 걸러내는데 사용

    상황 iterable에서 조건에 맞는 요소들을 선택하고자 할 때

    효과 주어진 조건을 만족하는 요소들만으로 새로운 iterable을 생성 (리스트, 튜플로 만들어지는게 아니라서 list(), tuple() 형변환 해줘야함)


    문법 : 변수 = filter(function, iterable)

        ① function (필수): 각 요소에 대해 실행되는 함수. 함수의 반환값이 True일때 해당 요소가 결과에 포함됨.

    입력값 : ① 보통 lambda로 표현하는 단순한 기능의 함수 / ② 리스트, range, 문자열

    리턴값 filter 객체를 반환하는 iterator이다.


    ※ 비교 : in 연산자랑 set() - set()과 filter 함수의 차이점이 있다. 

    filter 함수 : 매개변수로 오는 함수에 참인 경우에만 해당 요소를 포함시킴

    in 연산자, set() : 직접적으로 요소의 포함 여부를 확인함.  


    예시 
    words = ["apple", "banana", "kiwi", "grape", "orange"]
    long_words = list(filter(lambda word: len(word) >= 3, words))
    print(long_words)  # 출력: ["apple", "banana", "kiwi", "grape", "orange"]
    
    
    values = [1, None, 3, None, 5, 6, None, 8]
    filtered_values = list(filter(lambda x: x is not None, values))
    print(filtered_values)  # 출력: [1, 3, 5, 6, 8]



    ② 집합 연산자

    목적 : 집합의 관계 확인 = 부분집합, 같음여부, 합집합, 차집합, 대칭차집합

    입력값 : 집합 두개

    리턴값 :  True / False


    - 부분집합 연산자     >= 또는 <= 

    A = {1, 2}
    B = {1, 2, 3, 4}
    check = A <= B  # True
    check2 = A >= B # False 


    - 같음 연산자         ==

    A = {1, 2}
    B = {1, 2}
    is_equal = A == B  # True


    - 합집합 연산자       |

    A = {1, 2, 3}
    B = {3, 4, 5}
    union_set = A | B  # {1, 2, 3, 4, 5}


    - 교집합 연산자       &

    A = {1, 2, 3}
    B = {3, 4, 5}
    intersection_set = A & B  # {3}


    - 차집합 연산자       -

    A = {1, 2, 3, 4}
    B = {3, 4}
    difference_set = A - B  # {1, 2}


    - 대칭 차집합 연산자    ^

    두 집합의 대칭 차집합을 반환 (두 집합 중 하나에만 속하는 원소들의 집합).

    A = {1, 2, 3, 4}
    B = {3, 4, 5}
    symmetric_difference_set = A ^ B  # {1, 2, 5}




    댓글

    이 블로그의 인기 게시물

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

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

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