DATA ANALYSIS/TIL

[Day9] Python 심화(1)

yel1nk 2023. 5. 8. 17:37

args, kwargs

def add(*x, y):
    print(sum(x) + int(y))  # '3' -> 3

add(1, 2, y='3')  # 6
def function(*a, **b):
    print(a)
    print(b)

# 1. 어떤 값이 나올까?
# 2. 이 값은 어떤 자료형태인가? - 리스트, 튜플, 셋, 딕셔너리
function(41)
# (41,)
# {}
function(1, 2, 3, 4, 5)
# (1, 2, 3, 4, 5)
# {}
function(x=3)
# ()
# {'x': 3}
function(x=3, y=4)
# ()
# {'x': 3, 'y': 4}
function(1, 2, 3, 4, 5, x=3, y=4)
# (1, 2, 3, 4, 5)
# {'x': 3, 'y': 4}

https://engineer-mole.tistory.com/279
파이썬 함수에서는 인수 개수를 변경할 수 있다. 위치 인수에 대해 첫번째, 두번째는 필수, 세번째 이후는 선택으로 정할 수 있는데, 임의로 개수가 변하는 인수를 가변 길이 인수라 부르고, *를 붙이면 가변 길이 인수가 된다. 지정한 인수가 튜플로 지정이 되고, args라는 변수명을 많이 사용한다.

  • 결국 동시에 여러 입력값을 주고 싶을때 사용한다.
  • *만 붙이면 아무 이름이나 사용해도 되긴한다.
  • Tuple처럼 사용이 가능하다. 굳이 리스트나 튜플로 변경하지 않아도 된다.
  • 가변인자는 들어오는 인자의 갯수가 언제나 변할 수 있다.
# 인자 앞 *는 패킹
def a_test(a, *args):
    print(a, args)

a_test(1, 2, 3, 4, 5, 6)  # a=1, *args=2~6
# 1 (2, 3, 4, 5, 6)
def b_test(a, **kwargs):
    print(a, kwargs)

b_test(1, b=2, c=3, d=4, e=5, f=6)  
# 1 {'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6}
# 변수 앞 *는 언패킹
def c_test(a, args):
    print(a, args)  # 그대로
    print(a, *args) # 언패킹

c_test(1, (2, 3, 4, 5, 6))
# 1 (2, 3, 4, 5, 6)
# 1 2 3 4 5 6
  • 가변 아규먼트(args, arguments)는 내가 원하는 여러가지 인자들을 가변인수로 받을 수 있습니다. 값들은 모두 tuple로 저장됩니다.
def func(x, y, *args):
    print(f"첫번째 값은 {x}")
    print(f"두번째 값은 {y}")
    if args:
        print(f"세번째 이후의 값은 {args}")

func(1, 2, 3, 4, 5)
# 첫번째 값은 1
# 두번째 값은 2
# 세번째 이후의 값은 (3, 4, 5)
  • **kwargs는 딕셔너리로 가변인수를 받을 수 있는 방법입니다. *args와 마찬가지로 고정인수와 가변인수 함께 쓸 수 있습니다.
  • args(arguments)는 튜플 형식으로 파라미터를 받는 반면 kwargs(keyworded arguments)는 딕셔너리 형태로 파라미터를 받습니다.
def func(x, y, **kwargs):
    print(f"첫번째 값은 {x}")
    print(f"두번째 값은 {y}")
    if kwargs:
        print(f"세번째 이후의 값은 {kwargs}")

func(x=1, y=2, z=3, w=4)
# 첫번째 값은 1
# 두번째 값은 2
# 세번째 이후의 값은 {'z': 3, 'w': 4}
  • 앞에는 args형식으로 뒤에는 kwargs형식으로 받게되면 정상적으로 작동합니다. 파라미터를 넣을때 순서를 바꾸거나 혼합하면 에러가 발생됩니다.
# 가변 길이 위치 인수와 키워드 인수 조합
def func(x, *args, **kwargs):
    print(x)
    print(args)
    print(kwargs)

func(1)  # 첫 번째 인수만 지정한 결과
# 1
# ()
# {}
func(1, 100, 200, 300, a="X", b="Y", c="Z")  # 길이가 변하는 인수를 지정한 결과
# 1
# (100, 200, 300)
# {'a': 'X', 'b': 'Y', 'c': 'Z'}
# 함수 호출시 인자가 더 많은 경우
def func(x, y, z, a, b, c):
    print(x, y, z, a, b, c)
    print(x + y + z + a + b + c)

param1 = [1, 2, 3]
param2 = {"a": 1, "b": 2, "c": 3}
func(*param1, **param2)
# 1 2 3 1 2 3
# 12
# 날짜 변수 다루기
def data_to_string(y, m, d):
    print(str(y) + "년 " + str(m) + "월 " + str(d) + "일") 

# * 사용 언패킹
date = (2023, 5, 8)
data_to_string(date[0], date[1], date[2])
data_to_string(*date)
data_to_string(*[2023, 5, 8])
data_to_string(2023, *(5, 8))
# data_to_string(date)  # error

# ** 사용 언패킹
date = {'y': 2023, 'm': 5, 'd': 8}
data_to_string(date['y'], date['m'], date['d'])
data_to_string(**date)
# 2023년 5월 8일
# 어떤 함수가 몇번 호출되었는지 확인 실행할때
def outer_function():
    """ 외부 함수 """
    count = 0
    def inner_function():
        """내부 함수"""
        nonlocal count  # nonlocal 함수는 저장이 가능한 함수 - count 값을 저장
        count += 1   
        print(f'실행횟수가 {count}회 실행되었습니다.')
    return inner_function

func1 = outer_function()
# 함수 실행
func1()     # 실행횟수가 1회 실행되었습니다.
func1()     # 실행횟수가 2회 실행되었습니다.
func1()     # 실행횟수가 3회 실행되었습니다.
# 데코레이터 - 기본 함수를 변경하지 않고 기능을 추가할 수 있다.
def add_message(f):
    """함수 앞뒤로 시작/종료 메세지를 추가하는 함수"""
    def new_func():
        print("처리를 시작합니다.")
        f()
        print("처리를 종료합니다.")
    return new_func

def sample_func():
    """실행 메세지를 표시하는 함수"""
    print("sample_func 함수 처리를 실행합니다.")

# sample_func에 대해 추가한 함수를 실행
deco_func = add_message(sample_func)
deco_func()
# 처리를 시작합니다.
# sample_func 함수 처리를 실행합니다.
# 처리를 종료합니다.

lambda

lambda()는 익명함수, 이름이 없는 함수

  • 일반적으로 사용할 수 있는 변수의 위치에 ( )(괄호)만 사용하지 않는다면 변수처럼 사용할 수 있으며, 호출할 때는 '( )'(괄호)를 사용해줌
def f(x, y):
    return x + y

# lambda 매개변수 : 결과
f = lambda x, y: x + y
f(1, 4)  # 5

map

Map은 mapping을 생각해보면 편한데, map(함수 이름, 리스트 데이터)라는 형태에 맞춰 함수 F에 ex의 요소를 매핑하라라는 뜻

# map(함수, 리스트 혹은 튜플)

# 첫번째 방법
def 제곱(x):
    return x ** 2
list(map(제곱, [1, 2, 3, 4]))

# 두번째 방법
list(map(lambda x : x ** 2, [1, 2, 3, 4]))
# [1, 4, 9, 16]

generator

  • map(f, ex) -> list(map(f, ex))
  • 시퀀스 자료형의 데이터를 처리할때 실행 시점의 값을 생성해서 효율적으로 메모리를 관리할 수 있게 함

https://wikidocs.net/22802
a = [1, 2, 3, 4, 5](iterable 객체)는 선언되어 중복 호출이 가능하지만,
gen = (x for x in range(3)) 으로 생성된 데이터는 객체가 아닙니다.
generator는 값을 넘겨주고 나면 값을 소비하고 더 이상 기억하지 않습니다. 그렇기 때문에 iterable 객체처럼 여러번 값을 가져올수가 없습니다.

ex = [1,2,3,4,5]
new_list = []
f = lambda x : x**2
for value in map(f, ex):
    new_list.append(value)
print(new_list)

# 리스트 컴프리 핸션
print([x ** 2 for x in ex])
# [1, 4, 9, 16, 25]
# lambda함수의 filter 기능 - 조건문
list(filter(lambda x : x > 90, range(100)))
# [91, 92, 93, 94, 95, 96, 97, 98, 99]

reduce

형제같은 함수가 reduce 함수를 모두 적용한 다음에, 모든 값을 통합하는 함수

from functools import reduce
print(reduce(lambda x, y : x + y, [1,2,3,4,5]))
# 15

x = 0
for y in [1,2,3,4,5]:
    x += y
print(x)

파일 입출력

  • 파일 여는 모드는 읽기(r), 쓰기(w), 추가(a) 등이 있음
f = open("파일명" , "파일 열기 모드")
f.close()

쓰기

f = open('python.txt', 'w')
s = ''
for i in range(1, 6):
    s += f'{i}명 참여 중입니다. \n'
f.write(s)
f.close()

# with문을 사용하면 open과 close를 한꺼번에 할 수 있음
with open('python.txt', 'w') as f:
    s = ''
    for i in range(1, 6):
        s += f'{i}명 참여 중입니다. \n'
    f.write(s)

읽기

1. read()

  • read은 파일의 전체 내용을 읽어올 수 있음
f = open('python.txt', 'r')
data = f.read()
print(data)
f.close()
# with문을 사용하면 open과 close를 한꺼번에 할 수 있음
with open('python.txt', 'r') as f:
    data = f.read()
    print(data)

2. readline()

f = open('python.txt', 'r')
while True:
    line = f.readline()
    if not line:
        break
    print(line)
f.close()

3. readlines()

  • readline은 파일의 텍스트 한 줄을 출력해 줄 뿐이지만, readlines는 전체 라인을 읽어옴
f = open('python.txt', 'r')
lines = f.readlines()
for line in lines:
    print(line, end='')
f.close()

4. readall()

  • readall은 파일의 전체 텍스트를 읽어옴
f = open("인공지능캠프.txt", 'r')
while True:
    line = f.readline()
  if not line: break
    print(line)
f.close()
with open('song.txt', 'r') as my_song_list:
      contents = my_song_list.read()
      word_list = contents.split(" ")
      line_list = contents.split("\n")
print(f"총 글자수는 {len(contents)}입니다.")
print(f"총 단어수는 {len(word_list)}입니다.")
print(f"총 줄수는 {len(line_list)}입니다.")

인코딩 utf-8 / cp949 / euc-kr

f = open("count_list.txt", 'w', encoding = 'utf8')
for i in range(1, 11):
    data = f'{i}번째입니다.\n'
    f.write(data)
f.close()
with open('count_list.txt', 'w', encoding = 'utf8') as f:
    for i in range(1,11):
        data = f'{i}번째입니다.\n'
        f.write(data)

pickle 모듈

  • 메모리에 로딩된 객체들을 연속적으로 사용할 수 있도록 Pickle 모듈 제공
  • 파일 여는 모드는 읽기(rb), 쓰기(wb) 등이 있음
import pickle

f = open('list.pickle', 'wb')
test = [1,2,3,4,5]
pickle.dump(test, f)
f.close()

f = open('list.pickle', 'rb')
test_pickle = pickle.load(f)
print(test_pickle)
# pickle은 클래스도 저장가능하다.
class Multiply(object):
    def __init__(self, multi):
        self.multi = multi
    def multiply(self, number):
        return number * self.multi

multi_test = Multiply(5)
multi_test.multiply(10)

f = open('multiply_object.pickle', 'wb')
pickle.dump(multi_test, f)
f.close()

f = open('multiply_object.pickle', 'rb')
multi_test = pickle.load(f)
multi_test.multiply(10)

csv 데이터

import csv
import os   

# 경로 지정
os.chdir('/content/sample_data')

f = open('test.csv', 'r', encoding = 'utf-8')
new = csv.reader(f)
# print(new)  # 준비 끝

# csv 파일 출력하기
a_list = []
for i in new:
    a_list.append(i)
print(a_list)

# 함수화 하기
def opencsv(filename):
    f = open(filename, 'r')
    reader = csv.reader(f)
    output = []
    for i in reader:
        output.append(i)
    return output
opencsv('test.csv')
a = [['구', '전체', '내국인', '외국인'], 
     ['관악구','519864','502089','17775'], 
     ['강남구','547602','542498','5104'], 
     ['송파구','686181', '679247', '6934'], 
     ['강동구','428547','424235','4312']]

# 새로운 데이터 읽기
f = open('abc.csv', 'w', newline = '')
new_csv = csv.writer(f, delimiter = ',')
new_csv.writerows(a)    # a 자료를 csv파일에 넣기
f.close()

b = [['구', '전체', '내국인', '외국인'], 
     ['송파구','686181', '679247', '6934']]

# 함수화 하기
def writecsv(filename, list):
    with open(filename, 'w', newline = '') as f:
        a = csv.writer(f, delimiter = ',')
        a.writerows(list)
writecsv('new_abc.csv', b)

'DATA ANALYSIS > TIL' 카테고리의 다른 글

[Day11] Python 심화(3)  (1) 2023.05.10
[Day10] Python 심화(2)  (1) 2023.05.09
[VOD] 같이 푸는 PYTHON [기초]  (0) 2023.05.04
[Day7] Python 기초(5)  (0) 2023.05.04
[Day6] Python 기초(4)  (0) 2023.05.03