etc/introducing python: 처음 시작하는 파이썬

3장: 파이 채우기; list, tuple, dictionary, set (리스트, 튜플, 딕셔너리, 셋)

seul chan 2017. 1. 11. 15:52

3.1. 리스트와 튜플

3.2 리스트

3.2.1. 리스트 생성: [] or list()

list() 로 빈 리스트 할당 가능

3.2.2. 다른 데이터 타입을 리스트로 변경

list() 로 다른 데이터 타입을 리스트로 변경 가능하다

  • list(cat): c, a, t로 구성된 list로 변환
  • 튜플 또한 list로 변경 가능 하다
  • 문자열 나누기: split()을 통해 리스트로 변환할 수 있다.
In [1]:
# 문자열 나누기 예시
birthday = '4/26/1992'
birthday.split('/')
Out[1]:
['4', '26', '1992']

3.2.3 offset으로 항목 얻기

  • string과 마찬가지로 적용
  • 위치에 맞지 않고 list range를 벗어나면 error

3.2.4 리스트의 리스트

리스트 안에 리스트가 포함 가능. 인덱스를 이중으로 사용해서 추출 가능하다

3.2.5. offset으로 항목을 바꿀 수 있다.

문자열과는 다르게 list는 가변하기 때문에 항목을 변경 가능하다

  • name_li = ['seulchan', 'suwon', 'dayoon']
  • name_li[2] = 'sui'
In [3]:
name_li = ['seulchan', 'suwon', 'dayoon']
name_li[2] = 'sui'
name_li
Out[3]:
['seulchan', 'suwon', 'sui']

3.2.6. slice

list_name[start:end:step]

3.2.7. 항목 추가: append()

리스트의 끝에 항목을 추가 한다.

3.2.8. 병합: extend() or +=

  • append와는 다르게 다른 리스트의 값들을 더해준다
In [12]:
animals = ['cow', 'cat', 'dog']
fruits = ['apple', 'grape']
animals += fruits
animals
Out[12]:
['cow', 'cat', 'dog', 'apple', 'grape']

3.2.9. offset, insert()로 항목 추가

  • append() : 단지 리스트의 끝에 항목 추가
  • insert() : 원하는 위치에 항목 추가 가능

list_name.insert(3, 'sth') 형식으로

In [17]:
animals.insert(3, 'bird')
animals
# animals[3] 자리에 bird가 추가되었다
# index를 벗어나면 마지막에 추가된다.
Out[17]:
['cow', 'cat', 'dog', 'bird', 'bird', 'bird', 'bird', 'bird', 'apple', 'grape']

3.2.10. offset으로 항목 삭제하기

  • del list_name[1]과 같은 방식으로 항목 삭제 가능
  • del은 리스트 함수가 아니라 파이썬 구문
  • 따라서 list_name[1].del() 을 수행 할 수 없다.
  • del 은 = 와 반대: 객체로부터 이름을 분리하고 메모리를 비워줌 (!!)

3.2.11 remove()로 항목 삭제

  • remove()로 그 항목을 삭제 가능
  • animals.remove('bird')

3.2.12 pop(): offset으로 항목을 얻은 뒤에 삭제

  • pop()은 리스트에서 항목을 가져오는 동시에 항목을 삭제한다.
  • 인자가 없으면 -1 (마지막 값) 사용

3.2.13 index() : 값으로 offset 찾기

  • 항목 값의 오프셋을 알고 싶다면 index(): offset을 알려줌

3.2.14 in: 존재 여부 확인

  • 'cow' in animals
  • boolean 값으로 결과가 나옴

3.2.15 count(): 특정 값이 얼마나 있는지 확인

3.2.16 join(): 문자열로 변환 (list to string)

  • split() 의 반대라고 생각하자
In [21]:
# 3.2.16 join/split 예제
friends = ['Harry', 'Ron', 'Hermine']
seperator = ' * '
joined = seperator.join(friends)
print(joined)
seperated = joined.split(seperator)
print(seperated)
seperated == friends
Harry * Ron * Hermine
['Harry', 'Ron', 'Hermine']
Out[21]:
True

3.2.17 정렬하기: sort()

  • sort(): 내부적으로 정렬
  • sorted(): 정렬된 복사본 반환
  • 숫자는 기본적으로 오름차순이다. 내림차순으로 변환하려면 (reserve=True)를 추가
In [23]:
marxes = ['Groucho', 'Chico', 'Harpo']
sorted_marxed = sorted(marxes) #sorted를 사용, sorted_marxed 라는 복사본 만듬
# 원본은 변경되지 않는다
print(sorted_marxed)
print(marxes)
['Chico', 'Groucho', 'Harpo']
['Groucho', 'Chico', 'Harpo']
In [29]:
numbers = [2, 1, 3, 5, 4]
numbers.sort(reverse=True) # 내림차순으로 정렬
numbers
Out[29]:
[5, 4, 3, 2, 1]

3.2.18 len()

항목 개수 얻기

3.2.19 copy()

  • 두개의 리스트틀 같게 설정해주면 한 리스트를 변경하면 다른 리스트도 변경된다
  • a = [1, 2, 3]
  • a = b, 이 상태에서 a를 변경해주면 b 또한 변경된다

리스트 복사하기

  • a = [1, 2, 3] / b = a.copy() / c = list(a) / d = a[:]
  • 위의 예제에서 b, c, d는 a의 복사본이기 때문에 b, c, d를 변경해도 a에 영향을 미치지 않는다
In [2]:
a = [1, 2, 3]
b = a.copy()
c = list(a)
d = a[:]
a[0] = 'testing'
print(a, b, c, d)
['testing', 2, 3] [1, 2, 3] [1, 2, 3] [1, 2, 3]

3.3 튜플 tuple

튜플은 리스트와 다르게 불변: 정의한 이후에는 추가, 삭제, 수정을 할 수 없다.

3.3.1 making tuple

  • empty_tuple = () # 빈 튜플 만들기
  • 하나 이상의 튜플 만들기에는 각 요소 뒤에 콤마(,)를 붙임
  • 두개 이상의 요소가 있으면 마지막 요소에 콤마를 붙이지 않는다
  • 튜플을 정의 할 때에는 괄호()를 붙일 필요 없이 뒤에 콤마를 붙이면 되지만, 괄호로 정의하는게 튜플인지 구분하기 쉽다.
  • 튜플은 한번에 여러 변수를 할당 가능: (예제) 이를 튜플 언패킹이라고 부른다
In [3]:
# 튜플 언패킹 예제
marx_tuple = ('Groucho', 'Chico', 'Harpo', )
In [6]:
a, b, c = marx_tuple
print(a, b, c)
Groucho Chico Harpo
In [7]:
a, b
Out[7]:
('Groucho', 'Chico')
  • 한 문장에서 값을 교환하기 위해 임시 변수를 쓰지 않고 튜플을 사용 가능(예제)
In [9]:
# 값 교환 예제
id_value = 'bartkim026'
password_val = 'password'
id_value, password_val = password_val, id_value
print(id_value, password_val) # 두개의 값이 바뀐 것을 확인할 수 있다
password bartkim026
  • tuple()은 다른 객체(리스트 등)를 튜플로 만들어준다.
In [10]:
animal_li = ['cat', 'dow', 'cow']
tuple(animal_li)
Out[10]:
('cat', 'dow', 'cow')

3.4 딕셔너리 dictionary

리스트와 비슷하지만 다른점

  • 순서를 따지지 않음
  • 0, 1과같은 offset으로 항목 선택 불가
  • 값(value)에 해당하는 고유의 키(key) 지정: 어떤 타입이 들어와도 괜찮다
  • 다른 언어에서는 연관배열(associative array, hash, hashmap 등으로 사용)

3.4.1 making dict: {}

  • empty_dict = {}
  • bierce = {"day" : "A peri9od of twenty-four hours} #형식으로 만든다

3.4.2 dict(): dict 형식으로 변환

dict() 함수를 통해 두 값으로 이뤄진 시퀀스를 딕셔너리로 변경할 수 있다.

  • list 형식 외에도 튜플, 문자열 등으로 된 시퀀스를 딕셔너리로 변경할 수 있다.
In [13]:
lol = [['a','b'], ['c','d'], ['e', 'f']] # 세 개의 리스트로 구성된 list
dict(lol) 
Out[13]:
{'a': 'b', 'c': 'd', 'e': 'f'}
In [15]:
# 두 문자열로 된 리스트
los = ['ab', 'cd', 'ef']
dict(los) # 어떤 원리로 이렇게 되는건지 잘 모르겠다. 문자열이 두 개면 한개씩 value, key로 들어가는 듯 하다
Out[15]:
{'a': 'b', 'c': 'd', 'e': 'f'}

3.4.3 항목 추가/변경하기 : [key]

키에 의해 참조되는 값을 할당하는 방식으로 항목을 쉽게 추가 가능하다. 이미 키가 존재하는 경우 그 값은 새 값으로 대체, 없으면 추가된다.

  • key값은 유일해야한다; 두 번 이상 사용하면 마지막 값이 승리
In [17]:
pythons_dict = {
    'champman' : 'Graham',
    'Cleese' : 'John',
    'Idle' : 'Eric', 
    'Jones' : 'Terry',
    'Palin' : 'Michael', 
}
pythons_dict
Out[17]:
{'Cleese': 'John',
 'Idle': 'Eric',
 'Jones': 'Terry',
 'Palin': 'Michael',
 'champman': 'Graham'}
In [18]:
# 멤버 추가하기 - Terry Gilliam 
pythons_dict['Gilliam'] = 'Gerry'
pythons_dict
Out[18]:
{'Cleese': 'John',
 'Gilliam': 'Gerry',
 'Idle': 'Eric',
 'Jones': 'Terry',
 'Palin': 'Michael',
 'champman': 'Graham'}
In [20]:
# 내용 수정하기: Gerry -> Terry
pythons_dict['Gilliam'] = 'Terry'
pythons_dict
Out[20]:
{'Cleese': 'John',
 'Gilliam': 'Terry',
 'Idle': 'Eric',
 'Jones': 'Terry',
 'Palin': 'Michael',
 'champman': 'Graham'}

3.4.4 update(): 딕셔너리 결합하기

update() 함수는 한 딕셔너리의 키, value를 복사에서 다른 딕셔너리에 붙여준다.

  • 이 때 같은 key 값이 있으면 두번째 딕셔너리 (update 한 dict)에 있는 값이 승리한다.

3.4.5 key와 del로 항목 삭제하기

del pythons_dict['Marx'] 형식으로 삭제 가능하다

3.4.6 모든 항목 삭제하기: clear()

key, value 모든 값을 삭제된다.

  • pythons_dict = {} 를 할당해도 마찬가지의 결과

3.4.7 in으로 키 멤버십 테스트하기

'Champman' in pythons_dict 형식으로 확인 가능하다

3.4.8 [key] 형식으로 value 얻기

  • python_dict['Champman'] 와 같이 key를 지정하여 상응하는 value를 얻을 수 있다. 만약 해당 key가 존재하지 않으면 error가 난다.
  • 이 문제를 피하기 위해서는 in 으로 테스트를 하는 방법이 있고
  • get()함수를 사용하면 된다. 키가 존재하면 그 값을, 존재하지 않으면 옵션값을 지정해서 출력 가능하다 (옵션이 없으면 None을 얻는다) - 예제
In [23]:
# get()함수 예제
pythons_dict.get('champman', 'not in dict')
Out[23]:
'Graham'
In [24]:
pythons_dict.get('no_name', 'not in dict')
Out[24]:
'not in dict'

3.4.9 keys(): 딕셔너리의 모든 키를 가져옴

signals.keys() 와 같은 형식을 사용

  • python2에서는 keys()가 리스트를 반환했지만
  • python3에서는 iterable key를 dict_keys()로 보여줄 뿐이다.
  • 이를 실제 리스트로 사용하기 위해서느 dick_keys 객체를 list()를 통해 list화 시켜야 한다. (예제)
In [28]:
signals = {
    "green":"go",
    "yellow":"go faster",
    "red":"smile for the camera"
}
signals.keys() # iterable key들을 보여줌
Out[28]:
dict_keys(['green', 'red', 'yellow'])
In [29]:
# 이를 리스트로 쓰기위해서는
list(signals.keys())
Out[29]:
['green', 'red', 'yellow']

3.4.10 values(): 모든 값 얻기

signals.values()로 모든 값을 얻을 수 있따.

3.4.11 items(): 모든 쌍의 key-value를 얻기

signals.items() 를 통해 값을 얻을 수 있다. 각 키와 값은 튜플로 반환된다.

In [30]:
signals.items()
Out[30]:
dict_items([('green', 'go'), ('red', 'smile for the camera'), ('yellow', 'go faster')])

3.4.12 copy():

리스트와 마찬가지로 signals = signals_2 로 할당하면 둘 다의 값이 변경된다. 이를 피하기 위해서는 copy()를 사용한다

3.5 set(셋)

셋은 각 항목이 유일해야 한다. dict과 마찬가지로 set 또한 순서가 없다. 중복을 피할때 사용

3.5.1 set() : 셋 생성하기

  • empty_set = set()
  • even_num_set = {0, 2, 4, 6, 8}
  • *empty_set = {} 와 같은 방식으로는 사용할 수 없다. 이러면 dict이 만들어진다

3.5.2 set()로 데이터 타입 변환

리스트, 문자열, 튜플, 딕셔너리로부터 set()을 활용해서 중복된 값을 버릴 수 있다 set('letters') 를 하면 하나 이상 나온 문자들이 나온다.

3.5.3 in값으로 값 멤버십 테스트?

일반적으로 사용되는 set의 용도이다. drinks라는 dict를 만들어서 아래에서 예제를 진행해보겠다

3.5.4 combination과 연산자: '집합'을 활용해볼 수 있다

아래에서 사용할 drinks의 예제 (for, if, in을 사용한 예제)를 set을 활용하여 간결하게 작성할 것이다

  • 교집합:set intersection operator는 &(셋 교집합 연산자)
  • 합집합:set union operator는 | (셋 합집합 연산자)
  • 차집합: set difference operator는 difference()
  • 대칭 차집합(한쪽 셋에는 있지만 양쪽 모두에 없는 exclusive): symmetric_difference(), ^ 

In [32]:
drinks = {
    'martini': {'vodka','vermouth'},
    'black russian':{'vodka','kahlua'},
    'white russian':{'cream', 'kahlua', 'vodka'},
    'manhattan': {'rye', 'vermouth', 'bitters'},
    'screwdriver': {'orange juice', 'vodka'},
} # value의 시퀀스는 set, drink 는 dict
In [36]:
#vodka 포함된 음료는?
for name, contents in drinks.items():
    if 'vodka' in contents:
        print(name)
screwdriver
white russian
black russian
martini
In [38]:
#vodka는 포함되지만 vermouth, cream은 제외하고 싶다면?
for name, contents in drinks.items():
    if 'vodka' in contents and not ('vermouth' in contents or 'cream' in contents):
        print(name)
screwdriver
black russian
In [39]:
# 3.5.4 예제
# orange juice or vermouth가 든 음료를 마시고 싶을때
for name, contents in drinks.items():
    if contents & {'vermouth', 'orange juice'}:
        print(name) 
screwdriver
manhattan
martini
In [42]:
# 위에서 했던 #vodka는 포함되지만 vermouth, cream은 제외하고 싶다면?
for name, contents in drinks.items():
    if 'vodka' in contents and not contents & {'vermouth', 'cream'}:
        print(name)
screwdriver
black russian
In [43]:
bruss = drinks['black russian']
wruss = drinks['white russian']
In [51]:
#교집합
a = {1, 2}
b = {2, 3}
a & b
a.intersection(b)
Out[51]:
{2}
In [47]:
bruss & wruss
Out[47]:
{'kahlua', 'vodka'}
In [50]:
# 합집합
a|b
a.union(b)
Out[50]:
{1, 2, 3}
In [52]:
bruss|wruss
Out[52]:
{'cream', 'kahlua', 'vodka'}
In [56]:
# 차집합: - 를 통해 쉽게 할 수 있다
a - b
b - a
bruss - wruss
wruss - bruss
Out[56]:
{'cream'}
In [57]:
# ^ (대칭 차집합: 한쪽에는 있고 양쪽 모드에 있는건 아님)
a ^ b
Out[57]:
{1, 3}
In [58]:
bruss ^ wruss
Out[58]:
{'cream'}
In [60]:
# <=, issubset() 함수: 부분집합 확인
bruss <= wruss
bruss.issubset(wruss)
Out[60]:
True
In [61]:
# >=, issuperset() 함수: 수퍼셋은 서브셋의 반대
wruss >= bruss
Out[61]:
True

3.7 자료구조를 더 크게

리스트, 튜플, 셋, 딕셔너리를 활용해서 크고 복잡한 자료구조를 만들 수 있다.

In [63]:
# 3.7 예제

marxes = ["Groucho", "Chico", "Harpo"]
pythons = ["Chapman", "Cleese", "Jones"]
stooges = ["Moe", "Curly", "Larry"]
In [65]:
# 튜플의 각 요소는 리스트
tuple_of_lists = marxes, pythons, stooges # 튜플을 만들 떄는 () 안에 넣지 않아도 됨
tuple_of_lists
Out[65]:
(['Groucho', 'Chico', 'Harpo'],
 ['Chapman', 'Cleese', 'Jones'],
 ['Moe', 'Curly', 'Larry'])
In [66]:
# 세 리스트를 한 리스트에
list_of_lists = [marxes, pythons, stooges]
list_of_lists
Out[66]:
[['Groucho', 'Chico', 'Harpo'],
 ['Chapman', 'Cleese', 'Jones'],
 ['Moe', 'Curly', 'Larry']]
In [67]:
# 리스트의 딕셔너리
dict_of_lists = {
    "Marxes": marxes,
    "Pythons": pythons,
    "Stooges": stooges
}
dict_of_lists
Out[67]:
{'Marxes': ['Groucho', 'Chico', 'Harpo'],
 'Pythons': ['Chapman', 'Cleese', 'Jones'],
 'Stooges': ['Moe', 'Curly', 'Larry']}
In [72]:
## 3.8 연습문제

#3.1 출생년도에 대한 year_lists
year_lists = [1980, 1981, 1982, 1983, 1984]
# 3.2.
year_lists[2]
# 3.3
year_lists[-1]
# 3.4
things = ["mozzarella", "cinderella", "salmonella"]
# 3.5 
things[1].title()
# 3.6 
things[0].upper()
# 3.7
things.remove("salmonella")
In [83]:
# 3.8
surprise = ["Groucho", "Chico", "Harpo"]
# 3.9 마지막 요소를 소문자로 변경한 뒤, 단어를 역전시킨 후, 첫 글자를 대문자로
surprise[-1].lower()[::-1].title()
# 3.10
Out[83]:
'Oprah'
In [97]:
# 3.10
e2f = {
    'dog' : 'chien',
    'cat' : 'chat',
    'walrus': 'morse'
}
print(e2f)
{'dog': 'chien', 'cat': 'chat', 'walrus': 'morse'}
In [85]:
# 3.11
f2e['walrus']
Out[85]:
'morse'
In [98]:
f2e = {}
In [99]:
# 3.12 f2e dict를 이용해서 e2f 딕셔너리를 만들어라
for eng, fren in e2f.items():
    f2e[fren] = eng
In [100]:
f2e
Out[100]:
{'chat': 'cat', 'chien': 'dog', 'morse': 'walrus'}
In [101]:
# 3.13 f2e dict를 사용해서 chien을 의미하는 영어 출력
f2e['chien']
Out[101]:
'dog'
In [106]:
# 3.14. ef2 의 eng key 출력
print(list(e2f.keys()))
# e2f.keys() 는 dict 자료 형태 -> 이를 list로 변경시켜야한다.
['dog', 'cat', 'walrus']
In [107]:
# 3.15 
life = {
    'animals':{
        'cats':'Henri',
        'octopi':'Grumpy',
        'emus':'Lucy'
    },
    'plants': {},
    'other':{}
}
In [108]:
#3.16 life의 최상위 키 출력
print(list(life.keys()))
['animals', 'plants', 'other']
In [109]:
# 3.17 life['animals']의 모든 키 출력
list(life['animals'].keys())
Out[109]:
['octopi', 'emus', 'cats']
In [110]:
life['animals']['cats']
Out[110]:
'Henri'
In [ ]: