본문 바로가기
Programming/Python

파이쏘닉 Pythonic 코드 쓰는 법

by Renechoi 2022. 10. 14.

 

부스트코스의 "머신러닝을 위한 파이썬" 강좌 필기 내용 

 

https://www.boostcourse.org/ai222/joinLectures/28027

 

# 일반 코드

colors = ["a", "b", "c", "d", "e"]
result = ""

for s in colors:
    result += s

# print(result)
# abcde


# pythonic code

colors = ["red", "blue", "green", "yellow"]
result = "".join(colors)

# print(result)
# redbluegreenyellow






### Split 함수 
'''칸을 기준으로 문자열을 나누어줌'''


items = 'zero one two three'.split()
# print(items)
# ['zero', 'one', 'two', 'three']

example = 'python,jquery,javascript'

# print(example.split(","))
# ['python', 'jquery', 'javascript']


'''각각의 값들을 매핑시켜주는 unpacking '''
example2 = 'python,jquery,javascript'

a, b, c = example2.split(",")
# python,jquery,javascript


example3 = 'cs50.gachon.edu'

subdomain, domain, tld = example3.split(".")
# print(example3)
# cs50.gachon.edu






### Join 함수 
'''split이 자르는데 목적이 있다면 
스트링으로 리스트를 합치는데 목적 '''

colors = ["red", "blue", "green", "yellow"]
result = "".join(colors)
# redbluegreenyellow

### join에도 -이나 . 같은 문자를 넣어서 붙는 위치에 특정 기호를 넣어줄 수 있음 






### List comprehension
'''
- 기존 리스트를 사용해서 간단히 다른 리스트를 만드는 기법
- 포괄적인 리스트, 포함되는 리스트라는 의미로 사용됨
- 파이썬에서 가장 많이 사용되는 기법 중 하나
- 일반적으로 for + append 보다 속도가 빠름 
'''


# 일반 기법 
result = []

for i in range(10):
    result.append(i)

# print(result)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]


# List Comprehension 
result = [i for i in range(10)]
# print(result)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

result = [i for i in range(10) if i % 2 == 0]   ## 필터를 같이 사용해서 조건 형성 => 짝수만 리스트 안에 넣게 된다 
# print(result)
# [0, 2, 4, 6, 8]




# Nested For loop 

word_1 = "Hello"
word_2 = "World"
result = [i+j for i in word_1 for j in word_2]

''' 원래는 아래와 같은 
for i in word_1 :
    for j in word_2 :
        i+j 

맨 처음 i가 word_1의 h값으로 고정되고 j값이 반복문으로 그 다음 알파벳들 돌아가는 형식 

'''

# print(result)
# ['HW', 'Ho', 'Hr', 'Hl', 'Hd', 'eW', 'eo', 'er', 'el', 'ed', 'lW', 'lo', 'lr', 'll', 'ld', 'lW', 'lo', 'lr', 'll', 'ld', 'oW', 'oo', 'or', 'ol', 'od']




case_1 = ["A", "B", "C"]
case_2 = ["D", "E", "A"]

result = [i+j for i in case_1 for j in case_2]           
# print(result)
# ['AD', 'AE', 'AA', 'BD', 'BE', 'BA', 'CD', 'CE', 'CA']

# if 문 추가
result = [i+j for i in case_1 for j in case_2 if not(i==j)]         ## 필터를 걸어서 같지 않을 경우에만 추가를 하는 방법 
result.sort()

# print(result)
# ['AD', 'AE', 'BA', 'BD', 'BE', 'CA', 'CD', 'CE']                  ## 겹치는 AA를 제외하고 출력함 


## 키르테시안 프로덕트 => for 룹 두개를 겹쳐서 모든 값을 찾아내는 방법에 사용 될 수 





words = 'The quick brown fox jumps over the lazy dog'.split()
# print(words)
# ['The', 'quick', 'brown', 'fox', 'jumps', 'over', 'the', 'lazy', 'dog']  단어별로 스플릿해서 리스트화 

stuff = [[w.upper(), w.lower(), len(w)] for w in words]                     # 리스트 안에 리스트를 하나 더 넣어서 2 차원 리스트 생성 
# print(stuff)
# [['THE', 'the', 3], ['QUICK', 'quick', 5], ['BROWN', 'brown', 5], ['FOX', 'fox', 3], ['JUMPS', 'jumps', 5], ['OVER', 'over', 4], ['THE', 'the', 3], ['LAZY', 'lazy', 4], ['DOG', 'dog', 3]]           # 해당  문자의 총 문자수를 같이 출력해주는 2dimention 

# for i in stuff:
#     print(i)



case_1 = ["A", "B", "C"]
case_2 = ["D", "E", "F"]

result = [a+b for a in case_1 for b in case_2]          # case_1 리스트의 A부터 고정이 되고 case2 리스트의 D, E, F 로 배분이 되면서 a+b를 만들어냄 
# print(result)
# ['AD', 'AE', 'AF', 'BD', 'BE', 'BF', 'CD', 'CE', 'CF']

result = [ [ a+b for a in case_1 ] for b in case_2]          # 리스트를 씌우면 case2의 요소들이 고정이 되므로 먼저 D값이 고정이 되고 case 1을 돌면서 찾는 요소들과 결합 => A + D / B + D / C + D => 끝나면 리스트 닫아주고 , 그 다음 E 고정 시키고 다시 돌림  
# print(result)
# [['AD', 'BD', 'CD'], ['AE', 'BE', 'CE'], ['AF', 'BF', 'CF']]







### Enumerate 
'''
List의 element를 추출할 때 번호를 붙여서 추출하는 방식 
'''

for i, v in enumerate(['tic', 'tac', 'toc']):
    None
    # print(i, v)     # 리스트를 돌리면서 i로 인덱싱을 해줌
    # 0 tic
    # 1 tac
    # 2 toc

    
    
myList = ["a", "b", "c", "d"]
# print(list(enumerate(myList)))
# [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]      번호가 붙은 튜플 리스트 


{i:j for i, j in enumerate('Gachon University is an academic institue located in South Korea'.split())}                         # split으로 단어들을 쪼개주고 enumerate를 써서 인덱스와 같이 돌려서 얻는 결과물 = 단어의 순서가 어떤 위치에 있는지 보여주게 되고 그걸 딕셔너리 타입으로 추출 
# {0: 'Gachon', 1: 'University', 2: 'is', 3: 'an', 4: 'academic', 5: 'institue', 6: 'located', 7: 'in', 8: 'South', 9: 'Korea'}



### Zip 
'''
두 개의 리스트 값을 병렬적으로 추출 '''

alist = ['a1', 'a2', 'a3']
blist = ['b1', 'b2', 'b3']

for a, b in zip(alist, blist):      # 같은 인덱스에 위치해 있는 값들을 공통적을 뽑아줌 
    None
    # print(a, b)
    # a1 b1
    # a2 b2       
    # a3 b3



a, b, c = zip((1, 2, 3), (10, 20, 30), (100, 200, 300))                 
# print(a, b, c)
# (1, 10, 100) (2, 20, 200) (3, 30, 300)      # 단순하게 묶어서 보여줌 

List_comprehension_plus_zip = [sum(x) for x in zip((1, 2, 3), (10, 20, 30), (100, 200, 300))]  # List comprehension과 같이 쓰일 때 
# 먼저 1, 10, 100이 x의 튜플형태로 들어가게 되었는데 sum을 해서 111로 합쳐지고 , 그것을 리스트 형태로 추출해줌 
# print(List_comprehension_plus_zip)
# [111, 222, 333]



alist = ['a1', 'a2', 'a3']
blist = ['b1', 'b2', 'b3']

for i, (a, b) in enumerate(zip(alist, blist)):      # Enumerate와 zip을 같이 사용 
    None
    # zip으로 같은 위치에 있는 값을 뽑아주고, index를 i의 값으로 붙여줌 
    # print(i, a, b)
    # 0 a1 b1
    # 1 a2 b2
    # 2 a3 b3
    
    
    
    
### 람다 Lambda 
''' 
함수 이름 없이 함수처럼 쓸 수 있는 익명함수 
파이썬3에서 권장은 안하지만 여전히 많이 쓰임 => pandas 와 같이 쓸 때 효율적으로 쓰일 수 있어 알아두면 좋다 
'''

def f(x,y):
    return x+y

# => 

f= lambda x, y : x + y


### Map & reduce = 람다랑 같이 쓰임 

# map 
'''sequence 자료형 각 엘레먼트에 동일한 function을 적용함 
'''

ex = [ 1,2,3,4,5 ]
f = lambda x : x ** 2        
# print(list(map(f,ex)))  #맵을 쓰면 바로 함수에 하나하나 요소들이 적용이 됨 
# [1, 4, 9, 16, 25]
# 하나하나 적용할 때 많이 쓰인다고 보면 됨 
# 파이썬 3에서는 list를 써 주어야 주소값이 아니라 value로서 출력이 됨 


f = lambda x, y : x + y
# print(list(map(f, ex, ex)))     # 한번에 두개의 인자를 넣어서 계산할 수 => zip을 쓰지 않고 두개에 대한 연산 
# [2, 4, 6, 8, 10] 


list(map(                                           # 람다와 같이 쓰일 때 필터를 걸어줄 수 있는데 조건을 만족시키지 않으면 나올 else 값도 반드시 주어야 함 
    lambda x : x ** 2 if x % 2 == 0 else x, 
    ex
))
# [1, 4, 3, 16, 5]

# 리스트 comprehension과 거의 비슷하게 사용할 수 있음 
# [ value ** 2 for value in ex]




# Reduce funcion
'''
- map 과 같이 쓰이는 경우가 많음 
- map function과 달리 list에 똑같은 함수를 적용해서 통합 
'''

from functools import reduce 
reduce(lambda x,y:x+y, [1,2,3,4,5])                 
# 처음에 x에 1이 들어가고 y에 2가 들어감 = 3이 된 상태에서 다시 3으로 더해줘서 6 = 다시 4 더해줘서 10 마지막 5 => 15 
# => sequence형 자료형에서 각각의 element 들을 하나하나 적용하면서 = 옆으로 가면서 적용하는 
# print(reduce(lambda x,y:x+y, [1,2,3,4,5]))
# 15 


def factorial(n):
    return reduce( lambda x, y : x*y, range(1,n+1))
# 예를들어 5! = > 5*4*3*2*1 => range에서 1~5값을 생성해주면 => reduece 함수를 써서 차례로 1*2, *3, *4 구하게 됨 





# Asterisk 
'''
- *을 의미 
- 단순 곱셈, 제곱, 가변인자 등에 활용 
=> 함수에서 쓸 때 유용하게 쓰임 
'''


def asterisk_test(a, *args):        # 처음에는 a 값이 들어가고 나머지는 한꺼번에 받아라 
    None
#     print(a, args)
#     print(type(args))
#     1 (2, 3, 4, 5, 6)
#     <class 'tuple'>

# asterisk_test(1,2,3,4,5,6)

## 몇 개의 값이 들어올지 모를 때 => 여러개의 값을 한 번에 받을 수 있음 


def asterisk_test_2(a, **kargs):        # 키워드 인자 = 마찬가지로 한번에 넘겨 줄 때 = a는 그냥 들어가게 되고 나머지는 딕트 타입으로 들어가게 됨 
    None
#     print(a, kargs)
#     print(type(kargs))
#     1 {'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6}
#     <class 'dict'>
    

# asterisk_test_2(1, b=2, c=3, d=4, e=5, f=6)





def asterisk_test_3(a, *args):        
    None
    # print(a, args[0])
    # print(type(args))
    # 1 2
    # <class 'tuple'>

# asterisk_test_3(1, *(2, 3, 4, 5, 6))      # 함수에 넣을 때 *을 붙여서 넣으면 unpacking이 된 상태로 들어가게 된다 
# asterisk_test_3(1, (2, 3, 4, 5, 6))       # 붙이지 않고 넣으면 튜플 타입으로 들어가게 됨 = 하나의 변수로서 들어가게 됨 

def asterisk_test_4(a, args):
    None
#     print(a, *args)                 # 튜플 타입으로 받은 것을 추출할 때 * 쓰면 unpacking을 해줌 
#     print(type(args))
#     1 2 3 4 5 6
#     <class 'tuple'>
    

# asterisk_test_4(1, (2,3,4,5,6))




a, b, c = ([1, 2], [3, 4], [5, 6])      # 3개의 element가 있는 1개의 튜플 = > 0 , 1 ,2 값으로 존재함
# print(a, b, c)
# [1, 2] [3, 4] [5, 6]

data = ([1, 2], [3, 4], [5, 6])         # 이것에 *를 해주어서 바로 풀어줌 
# print(*data)
# [1, 2] [3, 4] [5, 6]


def asterisk_test_5(a, b, c, d):
    None
    # print(a,b,c,d)
    # 10 1 2 3

    
data = {"b":1, "c":2, "d":3}
asterisk_test_5(10, **data)         # 10은 그냥 들어가게 되는데, 나머지는 data의 딕셔너리를 풀어서 value 값으로 들어가게 됨 




for data in zip(*([1, 2], [3, 4], [5, 6])):     # 먼저 unpacking을 하게 되고 [1,2] [3,4] [5,6] = 3개의 변수가 있게 된 상태에서 zip = 1,3,5 묶어주고 
    None
    # print(data)
    # print(sum(data))
    # (1, 3, 5)
    # 9
    # (2, 4, 6)
    # 12
        
    
    
def asterisk_test_6(a, b, c, d, e=0):
    None
    # print(a, b, c, d, e)
    # 10 3 2 1 56
data= {"d": 1, "c":2, "b":3, "e":56}
asterisk_test_6(10, **data)             ## dict 타입을 풀어서 넣어주게 된다

 

 

 

참고 영상 

 

10 Tips for Pythonic Code 

 

https://www.youtube.com/watch?v=_O23jIXsshs 

 

 

반응형