VSFe님의 github repository와 파이썬을 파이썬답게 강좌를 참고하여 작성하였습니다.
파이썬에서 *(asterisk)는 다음과 같은 상황에서 사용
- 입력 받은 list에서 첫번째, 마지막 값만 얻고 싶은 경우
- 입력 받은 list에서 첫번째, 마지막 값을 제외하고 싶은 경우
이런 경우 다음 예시와 같이 사용하면 된다.
_list = [1, 2, 3, 4, 5]
first_index, *rest, last_index = _list
print(rest) # 2 3 4
위의 예시에서 rest에 사용한 것은 가변인자로
인자의 갯수가 몇 개가 될지 확실하지 않은 경우에 사용.
first_index
, last_index
가 첫번째, 마지막 값을 가져가고, rest가 나머지를 가져간다.
Unpacking은 말그대로 풀어낸다는 뜻으로 list, tuple, set같은 컨테이너형 구조에서 모두 적용가능하다.
_list = [1, 2, 3, 4, 5]
print(_list) # [1, 2, 3, 4, 5]
print(*_list) # 1 2 3 4 5
그냥 _list
를 출력하면 리스트 형태가 그대로 나오지만, *(asterisk)를 사용하여 unpacking하면 풀어서 출력된다.
💡 Packing
a = 1, 2, 3
print(a) # (1, 2, 3)
Packing은 말그대로 묶는다는 뜻으로, 하나의 변수에 여러 값을 할당하면 튜플로 묶인다.
기본적인 List Comprehension은 파이썬 문법 부수기 포스트 참조
리스트 뿐만 아니라 tuple, set, dict도 만들 수 있다.
[심화 예시]
# 주어진 리스트를 그대로 담되, 15가 넘어가는 값은 15로 바꿔서 저장하기
_list = [i if i <= 15 else 15 for i in tmp]
# 값이 두개 들어있는 튜플을 받아 리스트를 생성하되, 튜플 내부의 값을 뒤집어서 저장하기
list_of_tuple = [(i, j) for i in range(100), for j in range(100, 0, -1)]
_list = [(j, i) for i, j in list_of_tuple]
# 두 개의 리스트를 합치되, 가능한 모든 조합을 저장하는 리스트를 만들기
x = [i for i in range(5)]
y = [i for i in range(5)]
_list = [(i, j) for i in x, for j in y]
앞 쪽에 붙는 if는 삼항 연산자의 if,
맨 끝에 붙는 if는 값을 for문의 if조건으로 값을 값을 넣을지, 뺄지 결정하는 조건
Dictionary와 Set이 있다는 것은 알지만 어디에 사용하면 좋은지, 어떻게 해야 잘 사용할 수 있는지 알아보자
Dictionary와 Set은 Hash Table 구조를 띄고 있어 삽입, 삭제, 탐색 연산의 시간복잡도가 이다.
초보자들이 값을 찾기 위해 보통 list에서 in을 사용하는데 이 경우엔 순차적으로 탐색하게 되므로 데이터 양이 많아질수록 많은 시간이 소요됨.
이럴 땐 set을 사용하자.
set을 사용하여 의 시간복잡도로 탐색 가능.
data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
_data_set = set(data)
for i in range(10000):
if i in _data_set:
print(1)
set(집합)은 또한 같은 값이 들어올 수 없기에 다음과 같이 응용이 가능하다.
# 중복된 값을 포함하는 리스트에서 중복값 제거
duplicate_element = [21, 31, 65, 21, 58, 94, 13, 31, 58]
completed_list = list(set(duplicate_element)) # 21, 31, 65, 58, 94, 13
# 소문자로 바꾼후 중복된 원소들 제거
test_list = ['Test', 'test', 'TEST', 'tteesstt']
converted_list = list(set(map(lambda string: string.lower(), test_list))) # test, tteesstt
dictionary는 키와 쌍으로 이루어져있다.
fruit = ['apple', 'grape', 'orange']
price = [3200, 15200, 9800]
_dict = {}
for i in range(len(price)):
_dict.append((fruit[i], price[i]))
# {'apple' : 3200, 'grape' : 15200, 'orange' : 9000}
여기서 zip을 활용하면 더 쉽게 dictionary를 만들 수 있다.
zip은 각 iterables의 요소들을 모으는 iterator를 만든다.
zip 함수에 서로 다른 길이의 리스트가 인자로 들어오는 경우 길이가 짧은 쪽까지만 이터레이션이 이루어진다.
fruit = ['apple', 'grape', 'orange']
price = [3200, 15200, 9800]
_dict = dict(zip(fruit, price))
# {'apple' : 3200, 'grape' : 15200, 'orange' : 9000}
딕셔너리에서 없는 값을 찾으려고 하면 오류가 난다.
이 때, setdefault
를 사용하면 값이 있을 땐 해당 값을 리턴하고, 값이 없을 때는 두번째 인자로 넘겨준 값을 추가하고 추가한 값을 리턴해준다.
fruit = ['apple', 'grape']
price = [3200, 15200]
_dict = dict(zip(fruit, price))
print(_dict.setdefault('strawberry', 0)) # 0
# {'apple': 3200, 'grape': 15200, 'strawberry': 0}
매번 setdefault를 실행하는 데에 번거로울 때 defaultdict을 이용하면 setdefault를 암묵적으로 실행해준다.
from collections import defaultdict
movie_review = [('Clementine', 5), ('Parasite', 4.5), ('Clementine', 5)]
index = defaultdict(list)
for review in movie_review:
index[review[0]].append(review[1])
# {'Clementine': [5, 5], 'Parasite': [4.5]}
print(index['Train to Busan']) # []
# {'Clementine': [5, 5], 'Parasite': [4.5], 'Train to Busan': []}
string = 'I am Hungry...'
print(string[::-1])
print("".join(reversed(string)))
첫 번째 방법은 모든 iterable한 데이터에서 사용 가능.
두 번째 방법은 역순으로 뒤집은 iterator 리턴하여 join
이나 for i in ~
구조 사용
이중 이상의 반복문에서 flag를 넣어 참/거짓 여부를 판단하여 중간에 break 하는 경우
[예제]
5개의 숫자를 차례로 곱해 나온 수가 제곱수면 found, 모든 수를 곱해도 제곱수가 나오지 않은 경우 not found 출력
import math
numbers = [int(input()) for _ in range(5)]
multiplied = 1
flag = True
for number in numbers:
multiplied *= number
if math.sqrt(multiplied) == int(math.sqrt(multiplied)):
flag = False
print('found')
break
if flag:
print('not found')
import math
numbers = [int(input()) for _ in range(5)]
multiplied = 1
for number in numbers:
multiplied *= number
if math.sqrt(multiplied) == int(math.sqrt(multiplied)):
print('found')
break
else:
print('not found')
break로 반복문을 탈출하지 않았다면 else 구간으로 진입.
정수를 나눈 몫과 나머지를 구해야 할 경우
a//b, a%b
를 사용할 수도 있지만 아주 큰 숫자를 다룰 때에는 divmod
도 사용할 수 있다.
참고로 divmod
사용 시 tuple 형태로 return 되기 때문에 unpacking을 이용할 수 있다.
a = 7
b = 5
print(a//b, a%b) # 1 2
print(*divmod(a,b)) # 1 2
n진수 → 10진수 변환 시 int(string, base)
사용
ljust(width, [fillchar])
center(width, [fillchar])
rjust(width, [fillchar])
fillchar 생략 시 공백으로 채워짐.
s = 'abc'
n = 7
s.ljust(n) # 좌측 정렬
s.center(n) # 가운데 정렬
s.rjust(n) # 우측 정렬
[출력]
abc
abc
abc
모든 소문자, 대문자, 대소문자, 숫자 가져오기
import string
string.ascii_lowercase # 소문자 abcdefghijklmnopqrstuvwxyz
string.ascii_uppercase # 대문자 ABCDEFGHIJKLMNOPQRSTUVWXYZ
string.ascii_letters # 대소문자 모두 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
string.digits # 숫자 0123456789
아주 큰 값을 할당 할 때, inf
를 사용한다. inf
는 어떤 숫자와 비교해도 무조건 크다고 판정된다.
-inf
도 사용가능
with - as
구문을 이용하면
1. 파일을 close 하지 않아도 된다: with - as
블록이 종료되면 파일이 자동 close
2. readlines가 EOF까지 읽으므로, while문 안에서 EOF 체크할 필요가 없다.
with open('myfile.txt') as file:
for line in file.readlines():
print(line.strip().split('\t'))