본문 바로가기
개발일지/Python

2022.02.04 파이썬 정복 11장 컬렉션, 람다

by 다니엘의 개발 이야기 2022. 2. 4.
320x100
# 11장 컬렉션 관리
'''
score = [88,95,70,100,99]
for s in score:
    print("성적 :",s)
'''

'''
# 해설 코드
score = [88,95,70,100,99]
no = 1
for s in score:
    print(str(no)+"번 학생의 성적: ",s)
    no +=1
'''
'''
score = [88,95,70,100,99]
num = 1
for i in score:
    print(str(num)+"번재 학생 칼국수는 몇점이예요?:",num,"점") # 흥미롭다. 이 부분에 있어서 어떤건 ,+모두 이음새가 가능한데 어떤 건 하나만 사용 가능하다.
    num +=1
'''

'''
score = [88,95,70,100,99]
for no in range(len(score)):
    print(str(no +1),"번 학생의 성적 :",score[no]) # TypeError: can only concatenate str (not "int") to str
                                                 # 이렇게 에러가 나왔다. 즉, 문자로만 이어붙임이 가능하다는 건데.
                                                # 어디까지가 +허용이고 어디까지가 , 허용인지 파악해보자.
'''
'''
score = [88,95,70,100,99]
for no, s in enumerate(score,1): # 출력은 이전과 같이 된다. 그런데 굳이 이렇게 할 필요가 있을까?
    print(str(no)+"번 학생의 성적 :",s)
# 수식을 볼때 생각이 불필요하게 많이 하게 하는 것 같다.
'''

'''
# 이건 흥미롭다. 두개의 별개의 리스트를 for문으로 돌리는 구조.
# 해설코드
yoil = ["월","화","수","목","금","토","일"]
food = ["갈비탕","순대국","칼국수","삼겹살"]
menu = zip(yoil, food) # 일종의 합병 같다.

for y, f in menu: # 단수가 아니라 복수로써 2개의 원소를 사용하기 시작하는 것 같다. for 문에서
    print("%s요일 메뉴 : %s"%(y,f))
'''
'''
# 흥미롭기 때문에 한번 보지 않고 복습해보자

yoil = ["월","화","수","목","금","토","일"]
food = ["갈비탕","순대국","칼국수","삼겹살"]
menu = zip(yoil,food)   # zip이 코드의 핵심이였다. - 실패 후 성공

for y,f in menu:
    print("%s요일에는 : %s"%(y,f))
    
# zip이 묶어주는 역할을 함으로 2개 이상의 원소에 대한 for문 활용이 성립되었다.
# 더욱 흥미로운 점은 yoil의 리스트는 7개인데 food의 리스트는 4개이다.
그렇다면 교차되는 4개의 리스트만 리턴되고 for문은 종료된다.
'''

# any 함수는 리스트안에 "참"이 한개라도 존재하는지 확인 후에 불린 값을 리턴
# all 함수는 리스트 안의 모든 값이 "참"인지 아닌지 확인 후에 불린 값을 리턴
'''
adult = [True,False,True,False]
print(any(adult))
print(all(adult))
'''
# =================================================================

# 람다 함수
'''
# 마침내 람다 함수가 나왔다. 개인적으로는 구글링 하면서 피보나치 수열 검토할때,
# 이게 정말 유용한 함수였다고 인식이 되었는데 드디어 만나게 되었다.
# 보통 10줄자리의 코드를 1~2줄로 끝내는 것이 가능케 하는 함수였다.
# 1. filter

def flunk(s):
    return s <60

score = [45,89,72,53,94]
for s in filter(flunk,score): # 보통 in 다음엔 range나 범위 확인이 가능한 리스트만 쓰였는데 여기는 좀 색다르다.
                            # 구조적으로 정의함수, 리스트가 연달아서 쓰였다.
                            # 정의함수가 쓰일때 (s)를 뒤에 달아놓았는데 그걸 쓰지 않고도 사용이 된다니.. 활용하기엔
                            # 너무 멀다.
    print(s)

# 보니깐 람다 함수를 이용하기 위한 시리즈 물 내장함수를 배우는 것 같다.     
'''
'''
#2. map
def half(s):
    return s/2

score = [45,89,72,53,94]
for s in map(half,score):
    print(s,end=",")
    
'''
'''
def sin(s):
    return s/2

score = [45,89,72,53,94]

for i in map(sin,score): # filter 로 했을때는 sin이 작동이 안되었엇는데 map으로 하니깐 되더라.
    print(i)            # filter의 용도는 크고 작음을 대조해볼때 확인이 가능한 것 같다.
'''

'''
def total(s,b):
    return s+b

score = [45,92,72,53,94]
bonus = [2,3,0,0,5]
for s in map(total, score, bonus):
    print(s,end=",")
'''

'''
def total(s,b):
    return s+b

score = [45,92,72,53,94]
bonus = [2,3,0,0,5]
for s in map(total,score,bonus):
    print(s,end=",")
'''
'''
# 본격 람다를 할때 가장 기본이 되는 것

lambda x:x+1 # 인수 x를 받아서 x+1을 리턴하는 람다 식이라고 한다.
# 하지만 아직은 어떻게 사용하는지에 대해서는 잘 모르겠다.

def increase(x):
    return x+1

print(increase(2))


score = [45,89,72,53,94]
for i in filter(lambda x:x <60,score): # 쉽게 60 미만의 수를 출력하라가 되는데, 굳이 람다로 복잡하게 만들 필요가 있나?
    print(i)
'''
'''
score = [45,89,72,53,94]
for i in map(lambda x:x / 2, score): #왜 굳이 람다를 쓸까? # 왜 굳이 람다에는 x:x라고 되어있는데 이게 뭔뜻일까?
    print(i,end=",")
'''
'''
score = [45,89,72,53,94]
for i in score:
    print(i/2,end=",")
    
# 내가 만들어 본건데 결과적으론 람다와 같다. 왜 람다를 쓸까.
'''

#졸라 간단하게 람다는 끝났다; 설명도 제대로 안해주고 이게 뭔 짓인가 싶다.

# ============================================================
# 컬렉션의 사본
# 이거는 해설 보면서 좀 놀랐다. 일반적인 상식과는 약간 다르지만 합리적이다.
'''
a= 3
b=a
print("a=%d,b=%d"%(a,b)) #a=3,b=3
# 처음 대입 이후에 기존 대입의 기준이 되는게 변경이 되더라도 따라가질 않는다.
# 이건 단점이자 장점일것같다. 보완적으로 따라서 움직이는 함수도 있지 않을까?


a = 5
print("a=%d, b=%d"%(a,b)) # a=5, b=3
# 이렇게 까지가 당연하게 연결 되는 거라고 한다.
# 이런경우가 이해는 잘 안되지만 메모리가 다른거라고 한다.

# 하지만 컬렉션의 경우에는 얘기가 다르다.

list1 =[1,2,3]
list2 = list1


list2[2] = 100
print(list1)
print(list2)
# 컬렉션을 어떻게 구분짓는지는 모르겠으나 컬렉션은 메모리주소가 동일하므로 함께 변경되는거라고 한다.
'''
'''
list1 =[1,2,3]
list2 = list1.copy() # 카피본을 만들어놓는 것이기 때문에 아마 메모리 값이 list1과 비교해서 다를 것 같다.

list2[1] = 100
print(list1)
print(list2)
'''
'''
list0 = ["a","b"]
list1 = [list0, 1,2]
list2 = list1.copy()

list2[0][1] = "c"
print(list1)
print(list2)
'''

'''
import copy
list0=["a","b"]
list1=[list0,1,2]
list2=copy.deepcopy(list1) # deepcopy?;

list1[0][1] = "c" # 놀라운건 이 부분을 list1로 하면 list2도 따라올 줄 알았는데, 그렇지 않았다. 남겨진 카피본이 이미 존재하는 느낌.
print(list1)
print(list2)
'''
'''
list1 = [1,2,3]
list2= list1
list3=list1.copy()

print("1==2", list1 is list2)
print("1==3", list1 is list3) # 값은 같은데 메모리값이 달라서 다른걸로 나오는 건가?
print("2 ==3", list2 is list3) # 이것도 위와 같은 원리?
'''
'''
a = 1
b = a
print("a=",a,"b=",b,":", a is b)
b = 2
print("a=",a,"b=",b,":",a is b)
'''
'''
# 1. 1~10 정수의 리스트 a와 각 정수의 제곱의 리스트 b를 만든 후 두 리스트를 합쳐 사전으로 만들고 6의 제곱을 검색하여 출력하라.

# 내가 풀어본 것 - 실패
list1=int([1,2,3,4,5,6,7,8,9,10])
list2=list1**2 # 여기서부터가 문제다. list1의 숫자가 int형이 아니라고 안되는데, 어떻게 전환을 해줘야하는지 모르겠다.
dict=list1+list2

print(dict)
'''

'''
# 해답 수식

a = [n for n in range(1,11)]
b = [n*n for n in range(1,11)] # a 리스트 안에 있는 원소들을 각각 제곱해 주는거구나.
dic = dict(zip(a,b)) # 개별적으로 할때는 zip으로 합쳐준다는 개념 자체가 떠오르질 않았다.
print(dic[6]) # 흥미로운 부분은 위의 zip으로 합쳐놓았을때 a 리스트가 b 리스트의 키값으로 사용되고 b리스트는 벨류로 사용된다는 점이였다.
# 때문에 여기서는 dic의 키값이 6으로 설정되어있기 때문에 6에 해당하는 벨류값을 뱉어내는 것이다.

# 내가 배껴본 수식
a = [n for n in range(1,11)] # 틀린포인트 1. []리스트 형식으로 감싸주질 않았다.
b = [n*n for n in range(1,11)] # 틀린포인트 1. []리스트 형식으로 감싸주질 않았다.
dic = dict(zip(a,b))
print(dic[6]) # # 틀린포인트 2. dict내의 6이라고 생각했는데, 정의된건 dic니깐 당연히 dic의 안에 있는 걸 사용하는 것이다.
'''
'''
# 한번 더 베껴본 수식 - 성공

a = [n for n in range(1,11)]
b = [n*n for n in range(1,11)]
dic = dict(zip(a,b))
print(dic[6])
'''

'''
# 2. price 리스트에 상품 가격 다섯 개가 저장되어 있다. 모든 상품의 가격을 20% 세일한 값으로 출력하라.

# 내가 시도해본 수식 - 실패
price = [1000,2000,3000]

for i in price:
    print(i*0.8) # int로 소수점 뒷자리 짤라내고 싶은데 어떻게 하는지 모르겠다.
'''

'''
# 해답 수식
price = [1000,2000,3000]

def sale(p):
    return p *0.8

price2 = map(sale,price) # 정의를 sale()로 하더니 이용은 sale, price로 하다니. 사실 이미 나왔던 내용 같고 합리적인것같다.
                        # 다만 눈에 아직은 잘 안익은 것 같다.
for p in price2:
    print(p,end=",")
    
# 결과는 내 수식과 같은데 쓸대없이 어려운것같다. 그러나 뭔가 나중에 유용할 것같은 느낌이 드니 익혀두자.
'''
'''
# 카피 수식

price = [1000,2000,3000]

def sale(p):
    return p*0.8

price2 = map(sale,price) # 중간에 이 부분이 기억이 안나서 배끼다 시피했다.- 다시
for i in price2:
    print(i,end=",")
'''

'''
price = [1000,2000,3000]

def sale(p):
    return p*0.8

price2= map(sale(price)) # 구조 자체가 sale 뒤에 ,를 쓰고  (p)를 대신 써줘도 되고 (price)로 써도 되는 건가?
                        # 그건 아닌것같다. map의 원리에 대해서 더 배우자.
                        # map을 쓸때는 함수, 사용할 리스트의 순서대로 적어준다.

for i in price2:
    print(i,end=",")
'''
'''
# 두번째 해설 - 람다버전

price = [1000,2000,3000]
price2=map(lambda p:p * 0.8,price) # 확실히 구조적 이해가 안간다. map과 함께 학습해두자.
                                    # 와.. 놀랍다. p:p*0.8의 의미는 "p값을 p*0.8로 한다. 라는 뜻이다.
for p in price2:
    print(p,end=",")


# 추가로 람다를 리스트형식으로 쓰고 람다스라는 출력문으로 뽑아내는것도 가능하다.
'''
'''
# 내가 시도해볼것 - 실패

price = [1000,2000,3000]
price2=lambda x:x*0.8,price

for i in price2:
    print(i,end=",") # 이대로 하면 그냥 출력값이 <function <lambda> at 0x00000211170BD3A0>,[1000, 2000, 3000], 라고 된다.
'''

'''
# 다시 시도 - 람다

price = [1000,2000,3000]

price2= map(lambda x:x*0.8,price) # 0/8이라고 한 오타 외에는 성공적으로 활용 가능했다.
                                # 생각외로 lambda는 완전히 익혔다. 기초적인것만 그런건진 몰라도.
                                # 하지만 map은 약간 덜 이해갔다.
for i in price2:
    print(i,end=",")
'''
300x250