## 리스트 컴프리헨션 (리스트 내포표현식)
# - 리스트가 벡터 연산이 안되는 점을 비교적 간단한 문법으로 가능하게 함
# - 리스트가 내부에 반복문/조건문의 축약형 형태 전달 가능

## 1. 문법
[리턴 for i(반복변수) in 대상]                          # 반복만 가능
[리턴 for i(반복변수) in 대상 if 조건]                  # esle 생략 가능
[참리턴 if 조건 else 거짓리턴 for i(반복변수) in 대상]   # else 생략 불가


[i * 1.1 for i in L1]
[i for i in L1 if i < 3]
['a' if i < 3 else 'b' for i in L1] # 반복 조건문 같이 사용시 else 넣을때

# =============================================================================
# #예제1) 아래 리스트에 10% 인상된 값 리턴 
# =============================================================================
L1 = [1,2,3,4,5]

# for문
L2 = []
for i in L1:
    L2.append(i *1.1)

# mappig
list(map(lambda x: x *1.1,L1))

# 리스트 컴프리헨션
[i * 1.1 for i in L1]

# =============================================================================
# #예제2) 아래 리스트에서 3보다 작은 값만 출력
# =============================================================================
L1 = [1,2,3,4,5]

# for문
l2 = []
for i in L1:
    if i < 3:
        l2.append(i)
l2

# mapping
f1 = lambda x : x if x < 3 else None # 람다는 if full문법 불가, else 생략 불가
list(map(f1,L1))

# 리스트 컴프리헨션
[i for i in L1 if i < 3] # 조건이 있을때 조건만 출력
[i for i in L1 if i < 3 else i * 3] # 불가

# =============================================================================
# #예제3) 아래 리스트에서 3보다 작으면 'a' 크거나 같으면 'b' 출력
# =============================================================================

['a' if i < 3 else 'b' for i in L1] # 반복/조건문 같이 사용하고 else 넣을때

# =============================================================================
# #[연습]
# =============================================================================
sal = ['9,900','25,000','13,000']
addr = ['a;b;c','aa;bb;cc','aaa;bbb;ccc']
comm = [1000,1500,2000]

# =============================================================================
# #1) sal의 10% 인상값 출력
# =============================================================================
outlist=[]
for i in sal:
    outlist.append(round(int(i.replace(',','')) * 1.1, 1))
outlist

list(map(lambda x : round(int(x.replace(',',''))*1.1,1),sal))

[int(i.replace(',','')) *1.1 for i in sal]


l2 = []
for i in sal:
    l2.append(int(i.replace(',',''))*1.1)
l2

list(map(lambda x : round(int(x.replace(',',''))*1.1,1),sal))
list(map(lambda x: x *1.1,L1))

[round(int(i.replace(',','')) * 1.1,1)  for i in sal] 

# =============================================================================
# #2) addr에서 각 두번째 값(b,bb,bbb)출력
# =============================================================================
outlist = []
for i in addr :
    outlist.append(i.split(';')[1])
outlist

list(map(lambda x : x.split(';')[1],addr))

[i.split(';')[1] for i in addr]

#[참고 - map에 인자 전달 방식]
f1 = lambda x , y: x.split(';')[y]
list(map(f1,addr,1))
 # 'int' object is not iterable, (1)에서 에러 - map에 숫자 전달 불가

list(map(f1,addr,[1]))  
# b만 출력 (addr,3과 [],1의반복 횟수가 일치하지 않아 앞만 전달)
# addr과 [1]의 반복횟수 불일치, 1번만 반복

list(map(f1,addr,[1,1,1]))
# addr과 반복횟수 맞춰서 전달 필요

########
l3 = []
for i in addr:
    l3.append(i.split(';')[1])
l3

f1 = lambda x : x.split(';')[1]
list(map(f1,addr))

[i.split(';')[1] for i in addr]

# =============================================================================
# #3) comm이 1500보다 큰 경우 'A' 아니면 'B'
# =============================================================================

['A' if i > 1500 else 'B' for i in comm]

## deep copy [:]
# - 기존 형식은 메모리 공유 (얕은 복사)
# - 복사본 = 원본, 이후 복사본 수정시 원본에도 수정내용 반영된다.
# 

L1 = [1,2,3]
L2 = L1     # 메모리 공유, 같은 대상으로 본다.(Alias)

L3 = L1[:]  # 메모리 분리, deep copy

L2[0] = 10
L2
L1
L3

# [참고 : 객체의 메모리 주소 확인]
id(L1) # 1386546217928
id(L2) # 1386546217928
id(L3) # 1386546331976

id(L1) == id(L2)
id(L1) != id(L3)


