- programmers > 2021 KAKAO BLIND RECRUITMENT > 메뉴 리뉴얼
2021.06.24
1 try
from itertools import combinations
from collections import defaultdict
def solution(orders, course):
order_dict_list = [defaultdict(int) for _ in range(len(course))]
for order in orders:
for idx, size in enumerate(course):
order_combinations = combinations(sorted(order), size)
for m in order_combinations:
order_dict_list[idx][m] += 1
answer = []
for menu_dict in order_dict_list:
if menu_dict:
result = sorted(menu_dict.items(), key=lambda x: x[1], reverse=True)
most_ordered = result[0][1]
for other in result:
if most_ordered > 1 and other[1] == most_ordered:
answer.append("".join(other[0]))
else:
break
return sorted(answer)
- 비낕 for문이 course를 기준으로 돈다면 2개의 for문을 하나로 만들 수 있을 것 같다.
- 바깥 for문을 courses로 바꿔주었다.
- python의 Counter과 most_common() 함수를 이용했다.
from itertools import combinations
from collections import Counter
def solution(orders, course):
result = []
# 각 course 값에 대해 코스요리 후보 구하기
for size in course:
# 크기가 현재 course의 size인 모든 조합 구하기
order_combinations = []
for order in orders:
order_combinations += combinations(sorted(order), size)
# 해당 course에서 가장 많이 주문된 메뉴 조합을 찾아서 result에 저장
most_ordered = Counter(order_combinations).most_common()
for menu, ordered_num in most_ordered:
if ordered_num > 1 and ordered_num == most_ordered[0][1]:
result.append("".join(menu))
return sorted(result)
Counter('hello world').most_common()
>> [('l', 3), ('o', 2), ('h', 1), ('e', 1), (' ', 1), ('w', 1), ('r', 1), ('d', 1)]
Counter('hello world').most_common(1) # 앞에서 1번째만 출력
>> [('l', 3)]
❌오답의 원인 :
+=
와append
- 위의 코드에서 사실 처음에는
order_combinations += combinations(sorted(order), size)
대신order_combinations.append(combinations(sorted(order), size))
를 사용했다.- 즉,
+=
대신append
를 사용했더니 틀린 결과가 나왔다. 왜 그럴까?📌
+=
와append
디버깅을 해보니까 다음과 같이 출력됐다.
# 1) append order_combinations.append(combinations(sorted(order), size)) print(order_combinations) >> <itertools.combinations object at 0x00000171A8C2A810> # 2) += order_combinations += combinations(sorted(order), size) print(order_combinations) >> [(1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)]
- 즉, combinations의 경우, 리턴 값이 다음과 같이
combinations(iterable: Iterable[_T], r: int) -> Iterable[Tuple[_T]]
인데,
append
를 하게 되면 Iterable 객체가 저장되기 때문에<itertools.combinations object at 0x00000171A8C2A810>
이렇게 출력됐던 것이다.
- 반면,
+=
를 하게 되면 신기하게 combinations의 리턴 값인<itertools.combinations object at 0x00000171A8C2A810>
를 자동으로 list로 변환해서 저장해주었다. 따라서 이후의 값이 제대로 나올 수 있었던 것이다.
+=
와 append
와 extend
# combinations(iterable: Iterable[_T], r: int) -> Iterable[Tuple[_T]]
result = combinations([1, 2, 3, 4, 5], 2)
print(result)
# >> <itertools.combinations object at 0x000001C6369CA8B0>
# 📌list(combinations)
result = list(combinations([1, 2, 3, 4, 5], 2))
print(result)
# [(1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)]
# 📌+= combinations
result = []
result += combinations([1, 2, 3, 4, 5], 2)
print(result)
# [(1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)]
# 📌extend(combinations)
result = []
result.extend(combinations([1, 2, 3, 4, 5], 2))
print(result)
# [(1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)]
# 📌append(list(combinations)) : 💡[[...]]꼴로 저장되는 것에 유의하자. 이중 list가 된다.💡
result = []
result.append(list(combinations([1, 2, 3, 4, 5], 2)))
print(result)
# [[(1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)]]