TIL#42 PYTHON advanced(1)

Dasom·2020년 8월 24일
0

python

목록 보기
34/50
post-thumbnail

list comprehension

다음과 같은 도시목록의 리스트가 주어졌을때, 도시이름이 S로 시작하지 않는 도시만 리스트로 만들 때 리스트 컴프리헨션을 사용하여 함수를 작성해 보세요.

cities = ["Tokyo","Shanghai","Jakarta","Seoul","Guangzhou","Beijing","Karachi","Shenzhen","Delhi"]

cities_not_start_s = [i for i in cities if i[0] != 'S']

print(cities_not_start_s)

# 출력값
['Tokyo', 'Jakarta', 'Guangzhou', 'Beijing', 'Karachi', 'Delhi']

다음과 같은 도시, 인구수가 튜플의 리스트로 주어졌을때, 키가 도시, 값이 인구수인 딕셔너리를 딕셔너리 컴프리헨션을 사용한 함수를 작성해 보세요.

population_of_city = [('Tokyo',36923000), ('Shanghai',34000000), ('Jakarta', 30000000), ('Seoul', 25514000),
 ('Guangzhou', 25000000), ('Beijing', 24900000), ('Karachi', 24300000), ('Shenzhen', 23300000), ('Delhi', 21753486)]

dict_city = {i:j for i, j in population_of_city}

print(dict_city)

# 출력값
{'Tokyo': 36923000, 'Shanghai': 34000000, 'Jakarta': 30000000, 'Seoul': 25514000, 'Guangzhou': 25000000, 
'Beijing': 24900000, 'Karachi': 24300000, 'Shenzhen': 23300000, 'Delhi': 21753486}

iterator

다음의 간단한 키를 출력하는 딕셔너리에 대한 for 문을 while문으로 구현해 보세요.

D = {'a':1, 'b':2, 'c':3}
for key in D.keys():
    print(key)

# while 문

D_2 = iter(D)   # iter : 반복 가능한 데이터를 입력받아 반복자를 반환하는 함수
while True:
    try:
        key = next(D_2)   # next : 반복자를 입력받아 다음 출력값을 반환하는 함수
    except StopIteration:
        break
    print(key)

generator

다음코드를 실행해보고 분석. lazy evaluation 이란 무엇인지와 장점 및 리스트 컴프리헨션과의 차이점에 대하여 설명해주세요.

evaluation 은 값을 구함 이라는 뜻이다. lazy evaluation은 느리게 값을 구한다는 뜻. 어떤 값이 실제로 쓰일 때까지 그 값의 계산을 뒤로 미루는 동작 방식이다. 어떤 값이 필요할때만 사용하기 때문에 시간과 메모리를 절약할 수 있다.

import time

L = [1, 2, 3]

def print_iter(iter):
    for element in iter:
        print(element)

def lazy_return(num):
    print("sleep 1s")
    time.sleep(1)
    return num

print("comprehension_list=")
comprehension_list = [ lazy_return(i) for i in L ]
print_iter(comprehension_list)

print("generator_exp=")
generator_exp = ( lazy_return(i) for i in L )
print_iter(generator_exp)
# comprehension_list 를 출력해보았다.

comprehension_list=
sleep 1s
sleep 1s
sleep 1s
[1, 2, 3]

# print_iter(comprehension_list) 을 실행하면
comprehension_list=
sleep 1s    # 1초 간격으로 출력된다
sleep 1s
sleep 1s
1           # 1 2 3 이 한번에 출력된다
2
3
# generator_exp 를 출력해 보았다

generator_exp=
<generator object <genexpr> at 0x102a8c190>

# print_iter(generator_exp) 를 실행하면
generator_exp=
sleep 1s   # 1
1          # 2
sleep 1s   # 2
2          # 3
sleep 1s   # 3
3          # 4 순서로 출력된다

차이점은 위의 출력값만 보아도 알 수 있다.
리스트 컴프리헨션은 함수 lazy_return 을 먼저 실행해서 값을 출력하고 리턴값은 한번에 리스트로 만들었기 때문에 print_iter 함수를 실행하여 요소 하나씩을 출력했을 때 sleep 1s 는 1초씩 간격을 두고 출력되지만 1, 2, 3 은 한번에 출력된다. 수행하는 시간이 길거나 list값이 큰 경우에는 그만큼의 메모리가 늘어난다.

제너레이터는 실제로 값을 사용할 때 함수가 실행이 된다.
그래서 제너레이터 표현식을 출력하였을 때는 함수를 실행한 출력값이 나오지 않는다. print_iter 를 실행하면 그 때 하나씩 sleep_func 함수를 실행하며 값을 출력한다. 필요할 때만 실행할 수 있기 때문에 그만큼 메모리를 절약할 수 있다.

Lambda

types 모듈에 LambdaType 외에도 어떤 타입들이 있는지 조사해 보세요.

import types

print(dir(types))

## 출력값
['AsyncGeneratorType', 'BuiltinFunctionType', 'BuiltinMethodType', 'CellType', 'ClassMethodDescriptorType', 'CodeType', 
'CoroutineType', 'DynamicClassAttribute', 'FrameType', 'FunctionType', 'GeneratorType', 'GetSetDescriptorType', 'LambdaType',
'MappingProxyType', 'MemberDescriptorType', 'MethodDescriptorType', 'MethodType', 'MethodWrapperType', 'ModuleType', 
'SimpleNamespace', 'TracebackType', 'WrapperDescriptorType', '_GeneratorWrapper', '__all__', '__builtins__', '__cached__', 
'__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_calculate_meta', '_cell_factory', 'coroutine', 
'new_class', 'prepare_class', 'resolve_bases']

함수를 람다식으로 바꾸기

# 다음과 같이 비밀번호의 길이와 대문자가 포함된것을 확인하는 간단한 함수가 있습니다.
def check_password(password):
    if len(password) < 8:
        return 'SHORT_PASSWORD'

    if not any(c.isupper() for c in password):
        return 'NO_CAPITAL_LETTER_PASSWORD'

    return True
    
# 이함수에 있는 if문 두개를 람다표현식을 이용하여 다음과 같은 형식으로 작성해 보세요.
# 아래의 lambdas 리스트안에 두개의 람다표현식을 작성해야하며 주석으로 표시된 프린트가 출력결과로 나와야 합니다.
lambdas = [
    lambda x: 'SHORT_PASSWORD' if len(x) < 8 else None,
    lambda x: 'NO_CAPITAL_LETTER_PASSWORD' if not any((i.isupper()) for i in x) else None
]

def check_password_using_lambda(password):
    for f in lambdas:
        if f(password) is not None:
            return f(password)

    return True


print(check_password_using_lambda('123'))  # SHORT_PASSWORD
print(check_password_using_lambda('12356789f'))  # NO_CAPITAL_LETTER_PASSWORD
print(check_password_using_lambda('123456789fF'))  # True
profile
개발자꿈나무🌲

0개의 댓글