프로그래머스 파이썬 기초 트레이닝 :: 배열 만들기 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 합니다.
제한 사항
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])
이 조건문에서 사용한 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
위의 코드처럼 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)
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 함수랑, <= 연산자가 무엇인지 잘 몰라서 정리를 해봤다.
① filter 함수
이 문제에서 in 부분 연산자, set() - set() 과 같은 기능을 기능을 하는 파이썬 내장함수이다.
목적 : iterable에서 특정 조건을 만족하는 요소들만을 걸러내는데 사용
상황 : iterable에서 조건에 맞는 요소들을 선택하고자 할 때
효과 : 주어진 조건을 만족하는 요소들만으로 새로운 iterable을 생성 (리스트, 튜플로 만들어지는게 아니라서 list(), tuple() 형변환 해줘야함)
문법 : 변수 = filter(function, iterable)
① function (필수): 각 요소에 대해 실행되는 함수. 함수의 반환값이 True일때 해당 요소가 결과에 포함됨.
입력값 : ① 보통 lambda로 표현하는 단순한 기능의 함수 / ② 리스트, range, 문자열
리턴값 : filter 객체를 반환하는 iterator이다.
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}
댓글
댓글 쓰기