AI Basic/Python

파이썬 기초 - 파이썬을 파이썬답게

2로 접어듦 2023. 2. 26. 18:56

이미지 출처: www.python.org

 

출처: https://school.programmers.co.kr/learn/courses/4008/lessons/13318

프로그래머스 강좌를 바탕으로 파이썬 코드를 작성할 때 유용하게 사용될 수 있는 함수들을 정리하였습니다.

map() 함수

map(func, iter): 반복가능한 객체에 대해 given function을 적용하여 map object로 반환한다.

func에는 int, str, list 등이 가능하며, custom 함수도 적용이 가능하다.

iterable object에 반복적인 함수 적용이 필요할 때 사용하는 듯 하다.

 

리턴형은 map 객체이기 때문에, list 혹은 tuple로 변환시켜주어야 한다.loop 함수를 쓰는 것보다 빠르게 함수를 처리할 수 있으며, 메모리 사용량을 줄일 수 있다.(map 객체를 사용하기 때문)

 

함수를 첫 번째 인자로 받는데, len이라고 하면 함수를 의미하고, len()이라고 하면 함수 호출 후 리턴값을 의미한다.

 

장점

  • 반복가능한 객체를 한 번에 처리할 수 있다.
  • map 객체를 반환하기 때문에, 메모리 사용량을 줄일 수 있다.
  • 파이썬의 람다 함수와 함께 사용하면 간편하다.

단점

  • map 함수는 한 번에 처리하기 때문에, 중간에 에러가 발생하면 남은 데이터를 처리하지 못한다.
  • 파이썬 3에서는 list로 변환해주어야 한다는 점이 번거롭다.
>>> a = [1.2, 2.5, 3.7, 4.6]
>>> a = list(map(int, a))
>>> a
[1, 2, 3, 4]

# or
num, base = map(int, input().strip().split(' '))

# or to return double of n
def addition(n):
    return n + n
 
# We double all numbers using map()
numbers = (1, 2, 3, 4)
result = map(addition, numbers)
print(list(result))

strip() 함수

strip([chars]) : 인자로 전달된 문자를 String의 왼쪽과 오른쪽에서 제거한다.

인자를 전달하지 않으면 String에서 공백을 제거한다.

여러 문자를 전달하면 그 문자와 동일한 것들을 모두 제거한다.

text = '0000000Water boils at 100 degrees 000'
print(text.lstrip('0'))
print(text.rstrip('0'))
print(text.strip('0'))

 

단점

  • 문자열의 중간에 있는 공백, 개행문자 등은 제거하지 못한다.
  • 인자를 전달하지 않으면 공백만 제거하기 때문에, 다른 문자를 제거하려면 추가적인 처리가 필요하다.
  • 문자열을 복사하여 처리하기 때문에, 처리 대상 문자열이 매우 큰 경우 메모리 사용량이 증가할 수 있다.

int() 함수 - 진법 변환 지원

int(x, base=10): int 함수는 진법 변환을 지원한다.

num = '3212'
base = 5
answer = int(num, base)
## 위 코드는 아래 코드보다 간결하다.

answer = 0
for idx, number in enumerate(num[::-1]):
    answer += int(number) * (base ** idx)

String Slicing, ‘:’

sequence[start:stop:step] 으로 사용한다.

stop is the ending index (exclusive), and step is the step size between elements.

[::-1] means that you are iterating over the string backwards(reverse)

my_list = [1, 2, 3, 4, 5]
reversed_list = my_list[::-1]
print(reversed_list)  # Output: [5, 4, 3, 2, 1]

ljust, center, rjust

string 메소드를 활용하여 string을 인자로 넘겨지는 n 값에 대해 정렬을 수행할 수 있다.

sting.ascii_lowercase, string.digits

string.ascii_lowercase와 같은 명령어로 ‘abcdefghijklmnopqrstuvwxyz’와 같은 string을 한번에 얻을 수 있다.

lower = string.ascii_lowercase
digits = string.digits
print(list(digits))
# 출력: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
print(list(map(int, digits)))
# 출력: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# 위와 같이 string으로 만들어지는 점 유의해야 하며, map으로 변환할 수 있다.

zip() 함수

zip(*iterables): 각 iterables의 요소들을 모으는 이터레이터를 만듭니다. 튜플의 이터레이터를 돌려주는데, i 번째 튜플은 각 인자로 전달된 시퀀스나 이터러블의 i 번째 요소를 포함합니다.

즉, 반복적인 것들을 묶어서 튜플로 반환 → 인덱싱을 하지 않아도 되게끔 편리하게 되는 경우가 많다.

서로 다른 길이의 리스트가 인자로 들어오면, 짧은 쪽까지만 이터레이션을 발생한다.

mylist = [1, 2, 3]
new_list = [40, 50, 60]
for i in zip(mylist, new_list):
    print (i)
# 출력
#(1, 40)
#(2, 50)
#(3, 60)

# 또는 아래와 같이 딕셔너리로도 만들 수 있다.
animals = ['cat', 'dog', 'lion']
sounds = ['meow', 'woof', 'roar']
answer = dict(zip(animals, sounds)) 
# {'cat': 'meow', 'dog': 'woof', 'lion': 'roar'}

# 행과 열을 뒤집어 보기
mylist = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
new_list = [[], [], []]

for i in range(len(mylist)):
    for j in range(len(mylist[i])):
        new_list[i].append(mylist[j][i])

# 더 간단하게,
mylist = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
new_list = list(map(list, zip(*mylist)))

애스터리스크 unpacking

파이썬에서 애스터리스크(*)는 튜플, 딕셔너리를 unpacking하는 데에 사용되기도 한다.

튜플의 경우* 하나만, 딕셔너리는 **두개를 사용해야 key, element를 리턴받을 수 있다(반복문 안에서)

 

For 문 한줄로 쓰기

# 1중 for문
for i in range(10):
	listA.append(i)

listA = [ i for i in range(10) ]
# list comprehension 덕분에 가능하다.

# 2중 for문 ... 뒤의 for일 수록 더 나중에 적용되는 for문이다.
my_list = [[1, 2], [3, 4], [5, 6]]
answer = [element for first_array in my_list for element in first_array]
# 아래와 같은 코드이다.
for first_array in my_list:
	for element in first_array:
		answer.append(element)

string.join(iterable)

iterable 객체의 원소들을 이어붙이는 데에 join 함수를 사용할 수 있다.
Return a string which is the concatenation of the strings in iterable.

iterable 원소 사이사이에 seperator를 insert해주는 메소드.

my_string = '12345'
separator = '-'
result = separator.join(my_string)
print(result) # 1-2-3-4-5

list flattening 하기(n 차원 list → n-1 차원 만들기)

1. import itertools -

itertools.chain.from_iterable

itertools.chain(my_list)

위 두 기능은 같은 역할을 수행한다(flatten input list)

my_list = [[1, 2], [3, 4], [5, 6]]
# way 1.
import itertools
my_list = list(itertools.chain.from_iterable(my_list))

# way 2.
my_list = list(itertools.chain(*my_list))

2. list comprehension

  • This method is also memory-efficient as it doesn't create any intermediate lists.
  • 차원을 하나만 줄이는 것이므로 for loop 는 두 개만 있으면 된다(가장 바깥의 for loop가 주어진 list의 한 꺼풀을 벗기는 역할이라고 이해하자)
# 2 차원 -> 1 차원
my_list = [[1, 2], [3, 4], [5, 6]]
[element for array in my_list for element in array]

# 3 차원 -> 2 차원
# Original 3D list
my_list_3d = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]

# Flattened 2D list using list comprehension
my_list_2d = [inner_list for outer_list in my_list_3d for inner_list in outer_list]

# Output
print(my_list_2d)
# Output: [[1, 2], [3, 4], [5, 6], [7, 8]]

3. numpy.flatten

  • not efficient if the input list is very small.
import numpy as np
my_list = [[1, 2], [3, 4], [5, 6]]
np.array(my_list).flatten().tolist()

Cartesian product 구하기(곱집합)

  • 예시) 두 스트링 'ABCD', 'xy' 의 곱집합은 Ax Ay Bx By Cx Cy Dx Dy 입니다.
  • import itertools, itertools.product를 이용하여 tuple 형태로 반환할 수 있다. 리턴형은 itertools 객체이므로, 리스트로 감싸거나 *로 unpacking한 뒤 가공해야한다.
import itertools

iterable1 = 'ABCD'
iterable2 = 'xy'
iterable3 = '1234'
print(list(itertools.product(iterable1, iterable2, iterable3)))
# [('A', 'x', '1'), ('A', 'x', '2'), ('A', 'x', '3'), ...
# 이를 연결된 문자형태로 만들기 위해서는 join을 사용하면 된다.

[ ''.join(i) i for i in itertools.product(iterable1, iterable2, iterable3)]
# itertools가 in 안으로도 들어가 unpacking이 가능한 것 같다. 왜 i로만 하는지는 모르겠으나.

For - else

C++ 에서 for loop를 돌릴 때, 특정 조건을 만나면 break 하는 경우가 있다. 이 경우, for loop를 모두 동작한 다음 나온 것인지, 특정 조건에서 break 한 것인지 구분할 수 없어 flag 변수를 사용한다.

Python에서는 그러나, for-else문으로 보다 간결하게 flag 사용 없이 코딩이 가능하다.

# Example code using for-else statement
my_list = [1, 2, 3, 4, 5]

for item in my_list:
    if item == 6:
        print("Item found!")
        break
else:
    print("Item not found.")

Python class 의 __str__ method

str built in function으로, 객체 정보를 알고 싶을 때 print(객체이름)을 통하여 호출하는 함수이다.

double underscore method, magic method등의 이름이 있다(__ 이런거)

# Example code using __str__ method

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return f"{self.name} ({self.age})"

person1 = Person("Alice", 30)
person2 = Person("Bob", 25)

print(person1)  # Output: Alice (30)
print(person2)  # Output: Bob (25)

기타 Built-in method in Python class

  • __ init __
  • if name == “main”:

해당 py file이 main 으로 호출되어 사용된다면 main이라는 이름을 가지게 되어 해당 조건문이 true.

해당 py file이 다른 py file에 import 되는 형태라면 main이라는 이름을 가지지 않아 해당 조건문이 false.

해당 파일들을 testing하고 싶을 때 유용하게 사용할 수 있다.

def my_function():
    print("This is my function")

if __name__ == "__main__":
    print("This file is being run as the main program")
    my_function()
else:
    print("This file is being imported as a module")
		print("here can be test code")
  • __ str __: ex. return str(self.items)
  • __ repr __: ex. return f”MyList({self.items})

str 이나 repr이나 string 으로 반환해주는 것은 동일하나, str은 사용자가 읽기 편한 format으로 출력해주기 위한 함수지만(display 용), repr은 내부에서 처리하기 편한 format으로 변환해주는 것이 특징이다(디버깅과 개발용 리턴)

그래서 str built-in 메소드를, Object 출력용으로 사용한다. (print(Object))

  • __ len __

객체를 len(Object)로 감싸면 호출되는 함수로, len을 출력하도록 작성할 수 있다.

  • __ getitem __

key값을 인자로 받아, value를 리턴하도록 하는 함수이다.

with 의 사용

with은 file, socket 등과 같은 resource에 사용된다.

with open('example.txt', 'r') as f:
    contents = f.read()
    print(contents)
# 파일에 오류가 생겨도 자동으로 닫힌다는 장점이 있다(f.close())

Combination and Permutation

import itertools, itertools.permutation과 itertools.combination으로 사용할 수 있다.

import itertools

pool = ['A', 'B', 'C']
print(list(map(''.join, itertools.permutations(pool)))) # 3개의 원소로 순열 만들기
print(list(map(''.join, itertools.permutations(pool, 2))))