
from collections import namedtuple
Person = namedtuple('Person', ['name', 'age', 'height'])
person = Person('Sua', 100, 180)
print(person[0], person[1], person[2]) # 출력 : Sua 100 180
print(person.name, person.age, person.height) # 출력 : Sua 100 180
Python의 collections 모듈에서 제공하는 튜플의 서브클래스이다.
필드 이름과 인덱스를 사용해서 데이터에 접근할 수 있는 튜플이다.
튜플처럼 가볍고 빠르지만 이름으로 데이터에 접근할 수 있어서 가독성이 좋다.
클래스처럼 사용 가능하지만 더 간단하게 선언할 수 있고 불변성을 유지한다.
Tri = 네임드 튜플
t = Tri(3,7) # 네임드 튜플 객체 생성
print(t[0],t[1]) #일반 튜플과 동일한 방법으로 접근 가능하다.
print(t.width , t.height) #일반 튜플과 달리 이름으로도 접근이 가능하다.
from collections import namedtuple
Tri = namedtuple('Tri',('width', 'height'))
t = Tri(3,7)
print(t[0],t[1]) # 출력 : 3 7
print(t.width , t.height) # 출력 : 3 7
Cirlce = 네임드 튜플
circle = Cirlce(10)
print(circle[0]) #10
print(circle.radius) #10
from collections import namedtuple
Cirlce = namedtuple('Circle', ['radius'])
circle = Cirlce(10)
print(circle[0]) # 출력 : 10
print(circle.radius) # 출력 : 10
dic1 = {'a' : 1, 'b' : 2, 'c' : 3}
dic2 = dict(a=1, b=2, c=3)
dic3 = dict(zip("abc",(1, 2, 3)))
dic4 = dict( [('a', 1), ('b', 2), ('c', 3)] )
# dic4 = dict( (('a', 1), ('b', 2), ('c', 3)) ) # 안쪽은 리스트, 튜플 둘 다 가능
print(dic1) # 출력 : {'a': 1, 'b': 2, 'c': 3}
print(dic2) # 출력 : {'a': 1, 'b': 2, 'c': 3}
print(dic3) # 출력 : {'a': 1, 'b': 2, 'c': 3}
print(dic4) # 출력 : {'a': 1, 'b': 2, 'c': 3}
a = [1, 2, 3]
b = ['x', 'y', 'z']
z = zip(a, b) # zip 객체 생성
print(list(z)) # [(1, 'x'), (2, 'y'), (3, 'z')] -> zip 객체 순회해서 결과 반환
print(list(z)) # [] -> 이미 순회가 끝났으므로 비어 있음
두 개 이상의 리스트, 튜플, 문자열 등의 이터러블을 나란히 묶어서 한 쌍씩 짝을 지어주는 함수이다.
그렇게 만든 짝을 하나씩 꺼낼 수 있는 이터레이터를 만들어준다.
(결과는 이터레이터로 반환되기 때문에 리스트 or 튜플로 변환해야 한다.)
zip( ) 함수는 결과를 이터레이터로 반환하기 때문에 메모리를 절약하면서 한 번에 하나씩 값을 처리한다.
한번 순회하면 zip 객체는 소진되므로 여러 번 사용하려면 리스트로 변환해서 저장하면 된다.
(('a', 1), ('b', 2), ('c', 3))
print(tuple(zip('abc', (1, 2, 3)))) # 출력 : (('a', 1), ('b', 2), ('c', 3))
# 출력 [('a',1,'one'),('b',2,'two'),('c',3,'three')]
dic = zip('abc', (1, 2, 3), ('one', 'two', 'three'))
print(list(dic))
def add(a, b, c):
return a + b + c
nums = [1, 2, 3]
print(add(*nums)) # 1, 2, 3을 풀어서 전달 -> 출력 : 6
def greet(name, age):
return f"Hello {name}, you are {age}!"
person = {'name': 'Sua', 'age': 100}
print(greet(**person)) # 키=값 형태로 전달 -> 출력 : Hello Sua, you are 100!
def sum_all(*nums) :
s = 0
for i in nums :
s += i
return s
print(sum_all(1,2,3)) # 출력 : 6
def func(**args) :
print(args)
func(a = 1, b = 2, c= 3) # 출력 : {'a': 1, 'b': 2, 'c': 3}
def who(a,b,c):
print(a,b,c ,sep=",")
d = dict(a=1,b=2,c=3)
# 출력 : ('a', 1),('b', 2),('c', 3)
who(*d.items()) # 출력 : ('a', 1),('b', 2),('c', 3)
a ,*b,c = 1,2,3,4
print(a,b,c)
def func(*args): # 튜플로 묶음
print(args)
둘 다 패킹의 역할을 하지만 목적과 결과 타입이 다르다.
변수에서 *를 사용할 때는 나머지 값을 리스트로 묶어서 저장한다.
나머지 값을 한 변수에 저장하기 위해서 사용된다.
함수 파라미터에서 *를 사용할 때는 여러 개의 포지셔널 인자를 튜플로 묶어서 함수 내부로 전달한다.
함수 호출 시 전달된 모든 포지셔널 인자를 하나의 튜플로 묶는다.
여러 포지셔널 인자를 한꺼번에 받기 위해 사용된다.
def func(*arg,**args):
print(arg)
print(args) #def print(*arg,**args):
# 출력 :
(1, 2, 3)
{'a': 1, 'b': 2}
func(1, 2, 3, a=1, b=2)
import sys
sys.version
# terminal에서 python -v 도 가능
from collections import OrderedDict
dic = {'a' : 1, 'b' : 2, 'c' : 3}
another_dic = {'c' : 3, 'b' : 2, 'a': 1}
print(dic == another_dic) # True
od = OrderedDict({'a' : 1, 'b' : 2, 'c' : 3})
another_od = OrderedDict({'c' : 3, 'b' : 2, 'a': 1})
print(od == another_od) # False
파이썬 3.7 버전 이후로는 입력한 순서대로 딕셔너리에 입력되고 있다고 하지만 딕셔너리 자체에 순서가 없기 때문에 같은 키 - 값 쌍을 가지면 동일하다고 판단한다.
OrderedDict는 입력된 순서를 저장하고 비교할 때도 순서까지 비교하기 때문에 입력 순서가 다른 경우엔 키 - 값이 같더라도 다르다고 판단한다.
os = {1, 2, 3, 5, 5}
os.add(6)
print(os) # 출력 : {1, 2, 3, 5, 6}
os.discard(2)
print(os) # 출력 : {1, 3, 5, 6}
fs = frozenset({1, 2, 3, 5, 5})
print(fs) # 출력 : frozenset({1, 2, 3, 5})
# fs.add(6) # 에러 발생
# fs.discard(6) # 에러 발생
set과 frozenset은 둘 다 집합 자료형으로 중복을 허용하지 않고 순서가 없다.
인덱스를 통해 접근할 수 없고 for문이나 in을 사용한 연산을 주로 사용한다.
집합 연산을 사용한다.
frozenset은 set과 동일하지만 요소들의 추가, 삭제가 불가능하다.
set은 mutable하지만 frozenset은 immutable하다.
arr = ['abc', 'bac', 'bca']
# arr.sort(key = lambda x: x[2])
def third_sort(t) :
return t[2]
arr.sort(key = third_sort)
print(arr) # 출력 : ['bca', 'abc', 'bac']
key 매개변수는 정렬의 기준을 정의하는 함수 or lambda를 받는다.
nums = [(3, 1),(2, 9),(0, 5)]
nums.sort(key = lambda x : x[0] + x[1], reverse = True)
print(nums) # 출력 : [(2, 9), (0, 5), (3, 1)]
오름차순이 기본값이며 reverse = True 를 넣으면 내림차순으로 정렬된다.
names = ['Julasdfdsaia','Yooadfn','Stevadfen']
names.sort(key = len)
print(names) # 출력 : ['Yooadfn', 'Stevadfen', 'Julasdfdsaia']
frozen_set = frozenset({1,2,3,5,5})
print(frozen_set)
frozen_set.add(6)
frozenset은 set과 달리 요소들을 추가, 삭제가 불가능하기 때문이다.
t = [3,3,3,7,7,'z','z']
print(t) # 출력 : [3,'z',7]
t = list(set(t))
print(t) # 출력 : [3,'z',7]
코드가 요상해보이지만... 중복을 없애려면 set을 써야하는데 출력 결과는 list로 보이길래....
어쩔 수 없이 저런 코드가 나왔다.
b_idx = sorted(range(len(b)), key=lambda k: b[k])
print(b_idx)
sorted는 정렬된 새로운 리스트를 반환한다.
0~(b-1)까지의 수를 저장한 리스트를 만들고 그 리스트를 b의 인덱스에 넣어서 나온 값을 기준으로 정렬한다.
b = [40, 10, 30, 20]
b_idx = sorted(range(len(b)), key=lambda k: b[k])
print(b_idx) # 출력: [1, 3, 2, 0] -> b의 값을 기준으로 정렬된 인덱스
b에 대한 정보가 부족해서 잘 와닿지 않을 수 있어서 예시 리스트를 만들어봤다.
세줄요약:
1.네임드 튜플은 클래스를 만드는 과정이다.
2. * 와 ** 쓰는 4가지 케이스를 이해하자.
3. 순서있는 dictionary 는 OrderedDict으로 객체를 생성하자.
def func(**args) :
print(args)
func(a = 1, b = 2, c= 3)
func('a'= 1, 'b' = 2, 'c'= 3) # 에러
보통 딕셔너리에 키 - 값을 넣을 때 {'a' : 1, 'b' : 2, 'c' : 3} 이런식으로 넣기도 하고
작은 따옴표, 큰 따옴표 없이 a가 오면 변수로 인식된다는 얘기를 들었어서 func('a'= 1, 'b' = 2, 'c'= 3) 가 맞을 것 같은데 에러가 나서 이해가 잘 가지 않는다...

func('a'= 1, 'b' = 2, 'c'= 3) 이 부분은 변수선언이 넘어간다고 생각하시면, 이해가 편하실것 같습니다. 'a' = 1 문자열 a에 1을 할당하는게 아니듯이, 함수에서 호출 할때는 변수 선언으로 넘기고, 함수를 넘겨 받는쪽에서 **agrs 로 받으면 문법적으로 변수를 문자열로 변환시켜 {'a':1 ~~} 받아낸다고 이해해 주시기 바랍니다.