study blog

Python 자료구조 3 - set 본문

Python/2. built in types

Python 자료구조 3 - set

ivo_lee 2020. 1. 26. 16:35

Set type

- { } 로 표현함

- dict {} 안에 key value로 구성

- set {}안에 요소만 들어감

a = {1,2,3}   # cf. dict: a ={"name":"gildong","age":20}
              # dict 표현 중 key 없고 요소만 있는 경우 set이라고 함
print(type(a))  # <class 'set'>

 

- set이라는 자료구조는 기본적으로 순서가 없음. 중복을 허용하지 않는 저장장소

a = set([1,2,3,4,5])  # list -> set
a = set({1,2,3,1,2,3,4,1,2}); print(a)  # {1, 2, 3, 4}
a = set('Hello'); print(a)   # 문자열은 list와 유사 -> {'e', 'H', 'o', 'l'}

# set의 연산

a = {1,2,3,4}  # set의 literal
b = {3,4,5,6}
# set -> 집합 (집합연산: 교집합, 차집합, 합집합)

 

교집합

a & b   # {3, 4}
a.intersection(b)  

합집합

a | b
a.union(b) # {1, 2, 3, 4, 5, 6}

차집합

a-b   # -가 set에 적용되면 차집합. {1, 2}
a.difference(b)

add(): set에 원하는 요소 1개를 추가할 때 사용

mySet = {1,2,3,4,5}
mySet.add(7)  

update(): 여러개를 set에 추가할 때 사용

mySet.update([10,11,12])

remove(): 삭제

mySet.remove(1)   # 1을 찾아서 삭제  # {2, 3, 4, 5, 7, 10, 11, 12}

[연습문제 1-1] 로또 프로그램
로또복권 5장 자동으로 구매(번호 6개 선택)
이번 주 로또 당첨번호를 생성하여 구매한 로또가 당첨이 되었는지 확인

6개의 번호가 다 맞으면 → 1등
5개의 번호가 다 맞으면 → 2등
4개의 번호가 다 맞으면 → 3등
3개의 번호가 다 맞으면 → 4등
5장의 로또번호가 몇 등에 당첨되었는지 출력해라. (로또 숫자는 1-45)

(+) 랜덤번호 추출은 다음의 코드를 이용하자.

import random       #외부기능 이용
a = random.randint(1,45)   # 1이상 45이하의 정수형 난수 생성 (둘다 inclusive)

 

# 방법 1. random.sample 함수 이용

num = range(46); myLotto = [0]*5

for i in range(5):
    myLotto[i] = random.sample(num,6)
print(myLotto)

realLotto = random.sample(num,6)
realLotto = set(realLotto)  # 교집합 연산 사용하기 위해 set으로 바꿔줌
result = [0]*5

for i in range(5):
    myLotto[i] = set(myLotto[i])

    if len( realLotto.intersection(myLotto[i]) )==6:
        result[i] = "1등"
    elif len( realLotto.intersection(myLotto[i]) )==5:
        result[i] = "2등"
    elif len( realLotto.intersection(myLotto[i]) )==4:
        result[i] = "3등"
    elif len( realLotto.intersection(myLotto[i]) )==3:
        result[i] = "4등"    
    else :
        result[i] = "꽝"
        
print(result)

[[12, 29, 36, 11, 21, 18], [18, 9, 25, 38, 6, 42], [23, 43, 41, 45, 30, 16], [5, 9, 33, 12, 32, 13], [24, 40, 18, 21, 30, 20]]

['', '', '', '4', '']

 

# 방법 1의 함수화 (결과만 출력)

import random       

def myFunc(num) :    # num: 로또 구매 장수
    ran = range(1,46); myLotto = [0]*num 
    
    for i in range(num):
        myLotto[i] = random.sample(ran,6)

    realLotto = random.sample(ran,6)
    realLotto = set(realLotto)  # 교집합 연산 사용하기 위해 set으로 바꿔줌
    result = [0]*num

    for i in range(num):
        myLotto[i] = set(myLotto[i])
        if len( realLotto.intersection(myLotto[i]) )==6:
            result[i] = "1등"
        elif len( realLotto.intersection(myLotto[i]) )==5:
            result[i] = "2등"
        elif len( realLotto.intersection(myLotto[i]) )==4:
            result[i] = "3등"
        elif len( realLotto.intersection(myLotto[i]) )==3:
            result[i] = "4등"    
        else :
            result[i] = "꽝"
    return(result)

print(myFunc(5))

['', '', '', '', '']

 

 

# 방법 2. list 안에 set 5(복권5) 만들기

import random       #외부기능 이용
a = random.randint(1,45)   # 1이상 45이하의 정수형 난수 생성 (둘다 inclusive)

(+) list와 set 이용해서 로또번호 만드는법

# list이용해서 로또번호 1개 만들기
res = []

while len(res)<6 :
    x = random.randint(1,45)
    res.append(x)

    if len(res)==len(set(res)):
        res = list(set(res))
    else:
        res.pop()
#print(res)


# set이용해서 로또번호 1개 만들기
s= set()
while len(s)<6:
    x = random.randint(1,45)
    s.add(x)

 

# set 사용해서 로또번호 5개 뽑기 → 리스트 안에 set

myL = list()

for i in range(5):
    s =set()   # 로또번호 1개 만들기 - set 사용
    while len(s)<6:
        x = random.randint(1,45)
        s.add(x)
    myL.append(s)

Lotto= set()  # 당첨번호 뽑기

while len(Lotto)<6:
    x = random.randint(1,45)
    Lotto.add(x)

myResult = [0]*5
for i in range(5):
    if len( Lotto.intersection(myL[i]) )==6:
        myResult[i] = "1등"
    elif len( Lotto.intersection(myL[i]) )==5:
        myResult[i] = "2등"
    elif len( Lotto.intersection(myL[i]) )==4:
        myResult[i] = "3등"
    elif len( Lotto.intersection(myL[i]) )==3:
        myResult[i] = "4등"    
    else:
        myResult[i] = "꽝"
print(myResult)

['', '', '', '', '']


[연습문제 1-2] 보너스번호 있는 복권 (보너스번호는 1-6중 하나)

1등: 6개의 번호 맞으면
2등: 5개의 번호 맞고 + 보너스번호가 맞으면
3등: 5개의 번호가 맞으면
4등: 4개의 번호가 맞으면
5등: 3개의 번호가 맞으면

 

# 방법1. 보너스번호 random.sample

import random       #외부기능 이용

def myBonus(num) :    # num: 로또 구매 장수
    ran = range(1,46);  myLotto = [0]*num ;
    for i in range(num):
        myLotto[i] = random.sample(ran,7)

    realLotto = random.sample(ran,7)
    realLottoBonus = realLotto.pop()
    realLotto = set(realLotto)  # 교집합 연산 사용하기 위해 set으로 바꿔줌

    result = [0]*num
    for i in range(num):
        myLotto[i] = set(myLotto[i])
        if len( realLotto.intersection(myLotto[i]) )==6:
            result[i] = "1등"
        elif len( realLotto.intersection(myLotto[i]) )==5 and myLotto.intersection(realLottoBonus)==1 :
            result[i] = "2등"
        elif len( realLotto.intersection(myLotto[i]) )==5:
            result[i] = "3등"
        elif len( realLotto.intersection(myLotto[i]) )==4:
            result[i] = "4등"   
        elif len( realLotto.intersection(myLotto[i]) )==3:
            result[i] = "5등"           
        else :
            result[i] = "꽝"
    return(result)
print(myBonus(5))

['', '', '', '', '']

 

# 방법 2. set 사용해서 로또번호 5개 뽑기 -> 리스트 안에 set

myL = list()

for i in range(1,6):  # 복권 5장 뽑을거다
    s =set()
    while len(s)<7:   # 숫자 7개 뽑기 - 보너스번호까지
        x = random.randint(1,45)
        s.add(x)
    myL.append(s)

Lotto= set()  # 당첨번호 뽑기 - 7개
while len(Lotto)<7:
    x = random.randint(1,45)
    Lotto.add(x)
    
realLottoBonus= Lotto.pop()
myResult = [0]*5
for i in range(5): 
    if len( Lotto.intersection(myL[i]) )==6:
        myResult[i] = "1등"
    elif len( Lotto.intersection(myL[i]) )==5 and myLotto.intersection(set(realLottoBonus))==1:
        myResult[i] = "2등"
    elif len( Lotto.intersection(myL[i]) )==5:
        myResult[i] = "3등"
    elif len( Lotto.intersection(myL[i]) )==4:
        myResult[i] = "4등"    
    elif len( Lotto.intersection(myL[i]) )==3:
        myResult[i] = "5등" 
    else:
        myResult[i] = "꽝"
print(myResult)

['', '', '', '', '']

 

# 방법 2 결과 자세히 출력

myL = list()

for i in range(1,6):  # 복권 5장 뽑을거다
    s =set()
    while len(s)<6:   # 숫자 7개 뽑기 - 보너스번호까지
        x = random.randint(1,45)
        s.add(x)
    myL.append(s) 

Lotto= set()  # 당첨번호 뽑기 - 7개
while len(Lotto)<7:
    x = random.randint(1,45)
    Lotto.add(x)
realLottoBonus= Lotto.pop()
print("당첨번호: {}, 보너스번호: {}".format(Lotto,realLottoBonus))

myResult = [0]*5
for i in range(5):
    if len( Lotto.intersection(myL[i]) )==6:
        myResult[i] = "1등"
        print(i+1,"번째 복권:",myL[i],"당첨여부:",myResult[i])

    elif len( Lotto.intersection(myL[i]) )==5 and myL.intersection(set(realLottoBonus))==1:
        myResult[i] = "2등"
        print(i+1,"번째 복권:",myL[i],"당첨여부:",myResult[i])

    elif len( Lotto.intersection(myL[i]) )==5:
        myResult[i] = "3등"
        print(i+1,"번째 복권:",myL[i],"당첨여부:",myResult[i])

    elif len( Lotto.intersection(myL[i]) )==4:
        myResult[i] = "4등"    
        print(i+1,"번째 복권:",myL[i],"당첨여부:",myResult[i])

    elif len( Lotto.intersection(myL[i]) )==3:
        myResult[i] = "5등" 
        print(i+1,"번째 복권:",myL[i],"당첨여부:",myResult[i])

    else:
        myResult[i] = "꽝"
        print(i+1,"번째 복권:",myL[i],"당첨여부:",myResult[i])
#print(myResult)

당첨번호: {41, 11, 24, 28, 29, 31}, 보너스번호: 2

1 번째 복권: {32, 2, 42, 44, 16, 26} 당첨여부:

2 번째 복권: {3, 35, 38, 44, 13, 20} 당첨여부:

3 번째 복권: {35, 39, 12, 15, 26, 29} 당첨여부:

4 번째 복권: {41, 15, 21, 23, 26, 29} 당첨여부:

5 번째 복권: {35, 3, 6, 10, 44, 30} 당첨여부:

 


[연습문제 1-3] 1등에 당첨되려면 평균적으로 얼마만큼의 돈을 투자해야 할까요? (로또 1장은 1,000원)

 

# 방법1.

mySum = 0
# myN = [0]*10

for i in range(0,10):
    Lotto= set()  # 당첨번호 뽑기 - 6개
    while len(Lotto)<6:
        x = random.randint(1,45)
        Lotto.add(x)

    myResult=0; n=0
    while myResult<1 :
        myLotto= set()    # 뽑은 로또번호 만들기
        while len(myLotto)<6:
            x = random.randint(1,45)
            myLotto.add(x)    # myLotto: 내가 뽑은 로또번호

        if len( Lotto.intersection(myLotto) )==6:
            myResult =1
        n += 1
    #myN[i] = n
    #mySum += myN[i] 
    mySum +=n

print(mySum*1000/10)  # 1000:1게임당 투자금액, 10: 시행횟수
#print("{}장 사야 1등에 당첨".format(mySum))
#print("비용:{:,}".format(mySum)*1000)
#print("평균 비용:{}".format(mySum*1000/10))

7353449800.0

  

# 방법2.

mySum = 0
myN = [0]*10
for i in range(0,10):
    Lotto= set()  # 당첨번호 뽑기 - 6개
    
    while len(Lotto)<6:
        x = random.randint(1,45)
        Lotto.add(x)

    myResult=0; n=0
    while myResult<1 :
        myLotto= set()    # 뽑은 로또번호 만들기
        
        while len(myLotto)<6:
            x = random.randint(1,45)
            myLotto.add(x)    # myLotto: 내가 뽑은 로또번호

        if len( Lotto.intersection(myLotto) )==6:
            myResult =1
        n += 1
    myN[i] = n 
print(myN)
#print(mySum*1000/10)  # 1000:1게임당 투자금액, 10: 시행횟수

 

[연습문제 2] 어떤 수를 소수의 곱으로만 나타내는 것을 소인수분해라고 한다. 이 소수들을 그 수의 소인수라고 한다.  (예를 들면 13195의 소인수는 5,7,13,29)
600851475143의 소인수 중 가장 큰 수는 얼마인가?
myX = 600851475143; myList=[]    # 600851475143

for i in range(2,myX):
    if myX%i==0:
        myList.append(i)   # myList: 약수 전체 구하기  

def myIden(n) :    # 값 1개가 소수인지 아닌지 판별하는 함수  - 소수면 true, 아니면 false로 출력
    result = 0

    for i in range(1,n):
        if n % i ==0:
            result = result+1
    if result==1:
        return(True)
    else:
        return(False)
#print(myIden(7))

myNum=[]
for i in range(len(myList)):
    if myIden(myList[i])==True:
        myNum.append(myList[i])
print(myNum)

 

Comments