KR_Set - somaz94/python-study GitHub Wiki
์งํฉ์ ์ค๋ณต์ ํ์ฉํ์ง ์๊ณ ์์๊ฐ ์๋ ์๋ฃํ์ด๋ค. ์ํ์ ์งํฉ๊ณผ ๋์ผํ ๊ฐ๋ ์ผ๋ก, ๊ต์งํฉ, ํฉ์งํฉ, ์ฐจ์งํฉ ๋ฑ์ ์งํฉ ์ฐ์ฐ์ด ๊ฐ๋ฅํ๋ค.
# ์งํฉ ์์ฑ ๋ฐฉ๋ฒ
empty = set() # ๋น ์งํฉ
numbers = {1, 2, 3} # ์ค๊ดํธ๋ก ์์ฑ
string_set = set("Hello") # ๋ฌธ์์ด๋ก ์์ฑ -> {'H', 'e', 'l', 'o'}
list_set = set([1, 2, 2, 3, 3]) # ๋ฆฌ์คํธ๋ก ์์ฑ -> {1, 2, 3}
โ ํน์ง:
- ์ค๋ณต์ ํ์ฉํ์ง ์์
- ์์๊ฐ ์์ (์ธ๋ฑ์ฑ ๋ถ๊ฐ)
- ๋ณ๊ฒฝ ๊ฐ๋ฅ(mutable)ํ ์๋ฃํ
s1 = {1, 2, 3, 4, 5}
s2 = {4, 5, 6, 7, 8}
# ๊ต์งํฉ
print(s1 & s2) # {4, 5}
print(s1.intersection(s2)) # {4, 5}
# ํฉ์งํฉ
print(s1 | s2) # {1, 2, 3, 4, 5, 6, 7, 8}
print(s1.union(s2)) # {1, 2, 3, 4, 5, 6, 7, 8}
# ์ฐจ์งํฉ
print(s1 - s2) # {1, 2, 3}
print(s1.difference(s2)) # {1, 2, 3}
# ๋์นญ์ฐจ์งํฉ (ํฉ์งํฉ - ๊ต์งํฉ)
print(s1 ^ s2) # {1, 2, 3, 6, 7, 8}
print(s1.symmetric_difference(s2)) # {1, 2, 3, 6, 7, 8}
โ ์ฐ์ฐ์์ ๋ฉ์๋:
-
&
,intersection()
: ๊ต์งํฉ -
|
,union()
: ํฉ์งํฉ -
-
,difference()
: ์ฐจ์งํฉ -
^
,symmetric_difference()
: ๋์นญ์ฐจ์งํฉ
# ์์ ์ถ๊ฐ
s = {1, 2, 3}
s.add(4) # ๋จ์ผ ์์ ์ถ๊ฐ
s.update([5, 6, 7]) # ์ฌ๋ฌ ์์ ์ถ๊ฐ
# ์์ ์ ๊ฑฐ
s.remove(4) # ์์ ์ ๊ฑฐ (์์ผ๋ฉด KeyError)
s.discard(4) # ์์ ์ ๊ฑฐ (์์ด๋ ์๋ฌ ์์)
s.pop() # ์์์ ์์ ์ ๊ฑฐ ํ ๋ฐํ
s.clear() # ๋ชจ๋ ์์ ์ ๊ฑฐ
โ ์ฃผ์ ๋ฉ์๋:
-
add()
: ์์ 1๊ฐ ์ถ๊ฐ -
update()
: ์ฌ๋ฌ ์์ ์ถ๊ฐ -
remove()
: ์์ ์ ๊ฑฐ (์์ผ๋ฉด ์๋ฌ) -
discard()
: ์์ ์ ๊ฑฐ (์์ด๋ ์๋ฌ ์์) -
pop()
: ์์์ ์์ ์ ๊ฑฐ ํ ๋ฐํ -
clear()
: ๋ชจ๋ ์์ ์ ๊ฑฐ
# ๋ฆฌ์คํธ์ ์ค๋ณต ์ ๊ฑฐ
numbers = [1, 2, 2, 3, 3, 3]
unique_numbers = list(set(numbers)) # [1, 2, 3]
# ํฌํจ ๊ด๊ณ ํ์ธ
s1 = {1, 2, 3}
s2 = {1, 2}
print(s2.issubset(s1)) # True (๋ถ๋ถ์งํฉ)
print(s1.issuperset(s2)) # True (์์์งํฉ)
# ๊ต์งํฉ ์ฌ๋ถ ํ์ธ
s3 = {4, 5}
print(s1.isdisjoint(s3)) # True (๊ต์งํฉ ์์)
โ ํ์ฉ Tip:
- ์ค๋ณต ์ ๊ฑฐ๊ฐ ํ์ํ ๋
- ์งํฉ ์ฐ์ฐ์ด ํ์ํ ๋
- ๋ฉค๋ฒ์ญ ํ ์คํธ๊ฐ ๋น๋ฒํ ๋
- ๋ฐ์ดํฐ์ ์ ์ผ์ฑ์ด ์ค์ํ ๋
์งํฉ ์ปดํ๋ฆฌํจ์ (Set Comprehension)์ ๋ฆฌ์คํธ ์ปดํ๋ฆฌํจ์ ๊ณผ ์ ์ฌํ๊ฒ ๊ฐ๊ฒฐํ ๋ฐฉ๋ฒ์ผ๋ก ์งํฉ์ ์์ฑํ๋ ๊ธฐ๋ฅ์ด๋ค.
# ๊ธฐ๋ณธ ํ์
squares = {x**2 for x in range(10)}
# {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}
# ์กฐ๊ฑด์ ์ถ๊ฐ
even_squares = {x**2 for x in range(10) if x % 2 == 0}
# {0, 4, 16, 36, 64}
# ๋ค์ค ์กฐ๊ฑด
mixed = {x for x in range(20) if x % 2 == 0 if x % 3 == 0}
# {0, 6, 12, 18} (2์ 3์ ๊ณต๋ฐฐ์)
# if-else ์ฌ์ฉ
categorized = {x if x % 2 == 0 else -x for x in range(10)}
# {0, -1, 2, -3, 4, -5, 6, -7, 8, -9}
# ๋ฌธ์์ด ์ฒ๋ฆฌ
words = ['hello', 'world', 'python', 'programming']
lengths = {len(word) for word in words}
# {5, 6, 11} (์ค๋ณต ์ ๊ฑฐ๋ ๋ฌธ์์ด ๊ธธ์ด)
โ ์งํฉ ์ปดํ๋ฆฌํจ์ Tip:
- ์ค๋ณต์ด ์๋์ผ๋ก ์ ๊ฑฐ๋๋ฏ๋ก ์ ์ผํ ๊ฐ๋ง ์ถ์ถํ ๋ ์ ์ฉํ๋ค
- ์งํฉ์ ์์๊ฐ ์๊ธฐ ๋๋ฌธ์ ๊ฒฐ๊ณผ์ ์์๋ ๋ณด์ฅ๋์ง ์๋๋ค
- ๋ฆฌ์คํธ ์ปดํ๋ฆฌํจ์ ๋ณด๋ค ๋ฉ๋ชจ๋ฆฌ ํจ์จ์ด ์ข์ ์ ์๋ค (์ค๋ณต ์ ๊ฑฐ ์)
- ๋ณต์กํ ์ฐ์ฐ์ ๊ฒฝ์ฐ ๊ฐ๋ ์ฑ์ ์ํด ์ผ๋ฐ ๋ฐ๋ณต๋ฌธ ์ฌ์ฉ์ ๊ณ ๋ คํ๋ค
ํ์ด์ฌ์ ๋ณ๊ฒฝํ ์ ์๋(immutable) ์งํฉ์ธ frozenset
์ ์ ๊ณตํ๋ค.
# frozenset ์์ฑ
immutable = frozenset([1, 2, 3, 4])
print(immutable) # frozenset({1, 2, 3, 4})
# ์งํฉ ์ฐ์ฐ์ ๊ฐ๋ฅ
normal_set = {3, 4, 5, 6}
print(immutable & normal_set) # frozenset({3, 4})
print(immutable | normal_set) # frozenset({1, 2, 3, 4, 5, 6})
# ๋ณ๊ฒฝ ์๋๋ ์ค๋ฅ ๋ฐ์
try:
immutable.add(5) # ์ค๋ฅ: 'frozenset' object has no attribute 'add'
except AttributeError as e:
print(e)
# ๋์
๋๋ฆฌ ํค๋ ์งํฉ ์์๋ก ์ฌ์ฉ ๊ฐ๋ฅ
set_of_sets = {frozenset({1, 2}), frozenset({3, 4})}
dict_with_sets = {frozenset({1, 2}): 'set1', frozenset({3, 4}): 'set2'}
โ frozenset ํน์ง:
- ํ๋ฒ ์์ฑ๋๋ฉด ๋ณ๊ฒฝ ๋ถ๊ฐ๋ฅ(immutable)ํ๋ค
- ์งํฉ ์ฐ์ฐ(ํฉ์งํฉ, ๊ต์งํฉ ๋ฑ)์ ๊ฐ๋ฅํ๋ค
- ํด์ ๊ฐ๋ฅ(hashable)ํ์ฌ ๋ค๋ฅธ ์งํฉ์ ์์๋ ๋์ ๋๋ฆฌ์ ํค๋ก ์ฌ์ฉํ ์ ์๋ค
- ์ฐธ์กฐ์ ์์ ์ฑ์ด ํ์ํ ๋ ์ฌ์ฉํ๋ค
์งํฉ์ ํด์ ํ ์ด๋ธ์ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌํ๋์ด ์์ด, ๋ฉค๋ฒ์ญ ๊ฒ์ฌ์ ์ค๋ณต ์ ๊ฑฐ์ ๋งค์ฐ ํจ์จ์ ์ด๋ค.
import timeit
import random
# ๋ฐ์ดํฐ ์ค๋น
size = 10000
data = list(range(size))
random.shuffle(data)
lookup_value = size - 1
# ๋ฆฌ์คํธ vs ์งํฉ ๋ฉค๋ฒ์ญ ๊ฒ์ฌ ์ฑ๋ฅ ๋น๊ต
list_time = timeit.timeit(
lambda: lookup_value in data,
number=1000
)
set_data = set(data)
set_time = timeit.timeit(
lambda: lookup_value in set_data,
number=1000
)
print(f"๋ฆฌ์คํธ ๊ฒ์ ์๊ฐ: {list_time:.6f}์ด")
print(f"์งํฉ ๊ฒ์ ์๊ฐ: {set_time:.6f}์ด")
print(f"์งํฉ์ด ์ฝ {list_time/set_time:.1f}๋ฐฐ ๋น ๋ฆ")
# ๊ต์งํฉ ๊ณ์ฐ ์ฑ๋ฅ (naive vs set)
def naive_intersection(list1, list2):
return [item for item in list1 if item in list2]
list1 = random.sample(range(size), size//2)
list2 = random.sample(range(size), size//2)
naive_time = timeit.timeit(
lambda: naive_intersection(list1, list2),
number=10
)
set_intersection_time = timeit.timeit(
lambda: set(list1) & set(list2),
number=10
)
print(f"์ผ๋ฐ ๊ต์งํฉ ๊ตฌํ: {naive_time:.6f}์ด")
print(f"์งํฉ ๊ต์งํฉ ์ฐ์ฐ: {set_intersection_time:.6f}์ด")
print(f"์งํฉ์ด ์ฝ {naive_time/set_intersection_time:.1f}๋ฐฐ ๋น ๋ฆ")
์งํฉ ์ฐ์ฐ์ ์๊ฐ ๋ณต์ก๋๋ ๋ค์๊ณผ ๊ฐ๋ค:
์ฐ์ฐ | ํ๊ท ์๊ฐ ๋ณต์ก๋ | ์ต์ ์๊ฐ ๋ณต์ก๋ |
---|---|---|
์์ ์ถ๊ฐ (add) | O(1) | O(n) |
์์ ์ ๊ฑฐ (remove, discard) | O(1) | O(n) |
์์ ํฌํจ ํ์ธ (in) | O(1) | O(n) |
ํฉ์งํฉ, ๊ต์งํฉ, ์ฐจ์งํฉ | O(len(s1) + len(s2)) | O(len(s1) * len(s2)) |
๋ณต์ฌ (copy) | O(n) | O(n) |
โ ์ฑ๋ฅ ๊ด๋ จ Tip:
- ๋ฉค๋ฒ์ญ ๊ฒ์ฌ๊ฐ ๋น๋ฒํ ๋๋ ๋ฆฌ์คํธ๋ณด๋ค ์งํฉ ์ฌ์ฉ์ด ํจ์จ์ ์ด๋ค
- ์งํฉ์ ์์๋ ํด์ ๊ฐ๋ฅ(hashable)ํด์ผ ํ๋ฏ๋ก ๋ถ๋ณ ๊ฐ์ฒด๋ง ์ฌ์ฉ ๊ฐ๋ฅํ๋ค
- ๋์ฉ๋ ๋ฐ์ดํฐ์์ ์ค๋ณต ์ ๊ฑฐ ์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ด ํฌ๊ฒ ์ค์ด๋ค ์ ์๋ค
- ์งํฉ ์ฐ์ฐ์ ์ผ๋ฐ์ ์ผ๋ก O(1)์ด์ง๋ง, ํด์ ์ถฉ๋์ด ๋ง์ ๊ฒฝ์ฐ ์ฑ๋ฅ์ด ์ ํ๋ ์ ์๋ค
# ๋จ์ด ๋ชฉ๋ก์์ ์ค๋ณต๊ณผ ํน์ ์กฐ๊ฑด ํํฐ๋ง
words = ['apple', 'banana', 'apple', 'cherry', 'date', 'banana', 'elderberry']
# ์ค๋ณต ์ ๊ฑฐ ๋ฐ 5๊ธ์ ์ด๊ณผ ๋จ์ด ํํฐ๋ง
filtered_words = {word for word in words if len(word) > 5}
print(filtered_words) # {'banana', 'cherry', 'elderberry'}
# ๋ค์๊ณผ ๊ฐ์ด๋ ํ์ฉ ๊ฐ๋ฅ
unique_sorted_words = sorted(set(words))
print(unique_sorted_words) # ['apple', 'banana', 'cherry', 'date', 'elderberry']
# ํ์๋ค์ ์๊ฐ ๊ณผ๋ชฉ ๋ถ์
student_courses = {
'Alice': {'math', 'physics', 'chemistry'},
'Bob': {'math', 'physics', 'biology'},
'Charlie': {'physics', 'biology', 'computer science'},
'David': {'math', 'computer science'}
}
# ๋ชจ๋ ๊ณผ๋ชฉ ๋ชฉ๋ก
all_courses = set()
for courses in student_courses.values():
all_courses.update(courses)
print(f"๊ฐ์ค๋ ๋ชจ๋ ๊ณผ๋ชฉ: {all_courses}")
# ๊ฐ์ฅ ์ธ๊ธฐ ์๋ ๊ณผ๋ชฉ ์ฐพ๊ธฐ
course_count = {}
for courses in student_courses.values():
for course in courses:
course_count[course] = course_count.get(course, 0) + 1
most_popular = max(course_count, key=course_count.get)
print(f"๊ฐ์ฅ ์ธ๊ธฐ ์๋ ๊ณผ๋ชฉ: {most_popular} ({course_count[most_popular]}๋ช
์๊ฐ)")
# ๋ชจ๋ ํ์์ด ๋ฃ๋ ๊ณตํต ๊ณผ๋ชฉ
common_courses = set.intersection(*student_courses.values())
print(f"๋ชจ๋ ํ์์ด ์๊ฐํ๋ ๊ณผ๋ชฉ: {common_courses if common_courses else '์์'}")
# ์ ์ด๋ ํ ํ์์ด ๋ฃ๋ ๊ณผ๋ชฉ
any_courses = set.union(*student_courses.values())
print(f"์ ์ด๋ ํ ํ์์ด ์๊ฐํ๋ ๊ณผ๋ชฉ: {any_courses}")
# Two Sum ๋ฌธ์ : ๋ฐฐ์ด์์ ํฉ์ด target์ธ ๋ ์์ ์ธ๋ฑ์ค ์ฐพ๊ธฐ
def two_sum(nums, target):
seen = set()
for num in nums:
complement = target - num
if complement in seen:
return [num, complement]
seen.add(num)
return None
print(two_sum([2, 7, 11, 15], 9)) # [7, 2]
# ๋ฌธ์์ด์์ ์ค๋ณต ์๋ ๊ฐ์ฅ ๊ธด ๋ถ๋ถ ๋ฌธ์์ด ์ฐพ๊ธฐ
def longest_substring_without_repeating(s):
char_set = set()
max_length = 0
i = 0
for j in range(len(s)):
while s[j] in char_set:
char_set.remove(s[i])
i += 1
char_set.add(s[j])
max_length = max(max_length, j - i + 1)
return max_length
print(longest_substring_without_repeating("abcabcbb")) # 3 (abc)
print(longest_substring_without_repeating("bbbbb")) # 1 (b)
print(longest_substring_without_repeating("pwwkew")) # 3 (wke)
# ๊ทธ๋ํ์์ ์ฐ๊ฒฐ ์์ ์ฐพ๊ธฐ
def connected_components(graph):
visited = set()
components = []
def dfs(node, component):
visited.add(node)
component.add(node)
for neighbor in graph.get(node, []):
if neighbor not in visited:
dfs(neighbor, component)
for node in graph:
if node not in visited:
component = set()
dfs(node, component)
components.append(component)
return components
# ์ธ์ ๋ฆฌ์คํธ๋ก ํํ๋ ๊ทธ๋ํ
graph = {
'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B', 'F'],
'F': ['C', 'E'],
'G': ['H'],
'H': ['G']
}
components = connected_components(graph)
print(f"์ฐ๊ฒฐ ์์์ ๊ฐ์: {len(components)}")
for i, component in enumerate(components, 1):
print(f"์ฐ๊ฒฐ ์์ {i}: {component}")
โ ํ์ฉ ์ฌ๋ก:
- ์ค๋ณต ์ ๊ฑฐ ๋ฐ ๊ณ ์ ๊ฐ ์ถ์ถ
- ์งํฉ ์ฐ์ฐ์ ์ด์ฉํ ๋ฐ์ดํฐ ๋ถ์
- ํจ์จ์ ์ธ ๊ฒ์ ๋ฐ ์กฐํ
- ๊ทธ๋ํ ์๊ณ ๋ฆฌ์ฆ ๊ตฌํ
- ์บ์ฑ ๋ฐ ๋ฉ๋ชจ๋ฆฌ ์ต์ ํ
- ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ ๊ฒ์ฆ