advanced_python CH3

code
advanced_python
jupyter
Author

Seongtaek

Published

May 28, 2023

Jupyter에서 실행하기

Basic Grammar 2

1 Advanced Python CH3

2 Tuple

불변한 데이터 타입, 변경 삭제 불가

tup = 4,5,6
tup
(4, 5, 6)
nested_tup = (4,5,6),(7,8)
nested_tup
((4, 5, 6), (7, 8))
tuple([4,0,2])
(4, 0, 2)
tup = tuple('study')
tup
('s', 't', 'u', 'd', 'y')
tup[0]
's'
### 잘못된 예시 : 변경 불가

tup = tuple(['foo', [1,2], True])
tup[2] = False
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

Cell In[10], line 4
      1 ### 잘못된 예시 : 변경 불가
      3 tup = tuple(['foo', [1,2], True])
----> 4 tup[2] = False


TypeError: 'tuple' object does not support item assignment
tup[1].append(3)
tup
('foo', [1, 2, 3], True)
(4, None, 'foo') + (6, 0) + ('bar',)
(4, None, 'foo', 6, 0, 'bar')
('foo','bar') * 4
('foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'bar')

3 Unpacking tuples

tuple의 각 요소들을 변수에 할당

tup = (4,5,6)
a,b,c = tup
b
5
tup = 4,5,(6,7)
a,b,(c,d) = tup
a,b,c
(4, 5, 6)
tmp = a
a = b
b = tmp

a, b =1,2
a
1
b,a = a,b
a
2
b
1
seq = [(1,2,3), (4,5,6), (7,8,9)]
for a,b,c in seq:
    print('a={0}, b={1}, c={2}'.format(a,b,c))
a=1, b=2, c=3
a=4, b=5, c=6
a=7, b=8, c=9
seq2 = [(4,4,4), (7,7,7), (9,9,9)]
for z,y,x in seq2:
    print("z={0}, y={1}, x={2}".format(z,y,x))
z=4, y=4, x=4
z=7, y=7, x=7
z=9, y=9, x=9
for a in seq:
    print(a)
(1, 2, 3)
(4, 5, 6)
(7, 8, 9)
for c in seq2:
    print(c)
(4, 4, 4)
(7, 7, 7)
(9, 9, 9)
# * 마크 : * 부터 출력X

values = 1,2,3,4,5
a,b, * rest = values
a,b
(1, 2)
rest
[3, 4, 5]
a,b, *_ = values
_
[3, 4, 5]
values2 = 9,9,0,1,1,5
z,x, * hi = values2
print(z,x)
print(hi)
9 9
[0, 1, 1, 5]

4 Tuple methods

a = (1,2,2,2,3,4,2)
a.count(2)
4

4.1 Quiz 1

숫자 2가 몇개 있는지 세는 코드를 loop문 이용해 만들기

count = 0
for i in a:
    if i ==2:
        count +=1
print(count)
4

5 List

a_list = list([2,3,7,None])
tup = ('foo','bar','baz')
b_list = list(tup)
a_list, b_list
([2, 3, 7, None], ['foo', 'bar', 'baz'])
b_list[1] = 'peekaboo'
b_list
['foo', 'peekaboo', 'baz']
gen = range(10)
gen
list(gen)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

6 Adding & Removing elements

b_list.append('dwarf')
b_list
['foo', 'peekaboo', 'baz', 'dwarf']
# 자리 지정 추가

b_list.insert(1, 'red')
b_list
['foo', 'red', 'peekaboo', 'baz', 'dwarf']
# pop : 제거

b_list.pop(2)
b_list
['foo', 'red', 'baz', 'dwarf']
# 추가

b_list.append('foo')
b_list
['foo', 'red', 'baz', 'dwarf', 'foo']
# 제거 : 앞에서부터 순서대로 삭제

b_list.remove('foo')
b_list
['red', 'baz', 'dwarf', 'foo']
'dwarf' in b_list, 'dwarf' not in b_list
(True, False)

7 Concatenating and combining lists

[4, None, 'foo'] + [7,8,(2,3)]
[4, None, 'foo', 7, 8, (2, 3)]
# extend : 콘캣 함수

x = [4, None,'foo']
x.extend([7,8,(2,3)])
x
[4, None, 'foo', 7, 8, (2, 3)]

8 Sorting

# 오름 차순

a = [7,2,5,1,3]
a.sort()
a
[1, 2, 3, 5, 7]
# key : 조건 ex) key=len 길이 순서
# 길이 같으면 원래 순서 유지

b = ['saw','small','He','foxes','six']
b.sort(key=len)
b
['He', 'saw', 'six', 'small', 'foxes']

9 Binary search and maintaining a sorted list

# bisect : 특정 값이 들어갈 위치 탐색

import bisect
c = [1,2,2,2,3,4,7]
bisect.bisect(c,2), bisect.bisect(c,5)
(4, 6)
# insort : 특정 값이 들어갈 위치에 삽입

bisect.insort(c,6)
c
[1, 2, 2, 2, 3, 4, 6, 7]

10 Slicing

seq = [7,2,3,7,5,6,0,1]
seq
[7, 2, 3, 7, 5, 6, 0, 1]
# 3번째 부터 4번째 전까지 (3번째) 선택 + 변경

seq[3:4] = [6,3]
seq
[7, 2, 3, 6, 3, 5, 6, 0, 1]
# 5번째 전까지 출력

seq[:5]
[7, 2, 3, 6, 3]
# 3번째 부터 출력

seq[3:]
[6, 3, 5, 6, 0, 1]
# 뒤에서 4개 출력

seq[-4:]
[5, 6, 0, 1]
# 뒤에서 끝 2개 제외 6개 출력

seq[-6:-2]
[6, 3, 5, 6]
# 앞에서부터 간격 2로 출력

seq[::2]
[7, 3, 3, 6, 1]
# 뒤에서부터 간격 1로 출력

seq[::-1]
[1, 0, 6, 5, 3, 6, 3, 2, 7]

10.1 Quiz 2

  • 1,0,6,5 출력
seq
[7, 2, 3, 6, 3, 5, 6, 0, 1]
seq[-4:][::-1]
[1, 0, 6, 5]
seq[:4:-1]
[1, 0, 6, 5]

11 do something with value

# enumerate() : 인덱스, 값 순회

some_list = ['foo','bar','baz']
mapping = {}
for i, v in enumerate(some_list):
    mapping[v] = i
mapping
{'foo': 0, 'bar': 1, 'baz': 2}
s = ['asd', 'zxc','qwe']
m = {}
for a,b in enumerate(s):
    m[b] = a
m   
{'asd': 0, 'zxc': 1, 'qwe': 2}
# sorted() : 작은것, 순서대로 정렬

sorted([7,1,2,6,0,3,2]), sorted('horse race')
([0, 1, 2, 2, 3, 6, 7], [' ', 'a', 'c', 'e', 'e', 'h', 'o', 'r', 'r', 's'])
# zip() : 순서쌍으로 묶기

seq1 = ['foo','bar','baz']
seq2 = ['one','two','three']
zipped = zip(seq1, seq2)
list(zipped)
[('foo', 'one'), ('bar', 'two'), ('baz', 'three')]
# 개수 안 맞으면 최소 개수 출력

seq3 = [False, True]
list(zip(seq1, seq2, seq3))
[('foo', 'one', False), ('bar', 'two', True)]
# enumerate() + zip() 활용

for i, (a,b) in enumerate(zip(seq1, seq2)):
    print('{0}: {1}, {2}'.format(i,a,b))
0: foo, one
1: bar, two
2: baz, three
for a,(b,c,d) in enumerate(zip(seq1,seq2,seq3)):
    print("{0}: {1}, {2}".format(a,b,c,d))
0: foo, one
1: bar, two
# reversed() : 거꾸로

list(reversed(range(10)))
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

12 dict

# key 값 : 'a','b', value 값 : 'some value',[1, 2, 3, 4]

empty_dict = {}
d1 = {'a' : 'some value', 'b' : [1,2,3,4]}
d1
{'a': 'some value', 'b': [1, 2, 3, 4]}
# 딕셔너리에 새로운 key-value 쌍 추가

d1['an integer'] = 7
d1
{'a': 'some value', 'b': [1, 2, 3, 4], 'an integer': 7}
# key에 대한 value값 반환

d1['b']
[1, 2, 3, 4]
d1['an integer']
7
'b' in d1
True
d1[5] = 'some value'
d1
{'a': 'some value', 'b': [1, 2, 3, 4], 'an integer': 7, 5: 'some value'}
d1['dummy'] = 'another value'
d1
{'a': 'some value',
 'b': [1, 2, 3, 4],
 'an integer': 7,
 5: 'some value',
 'dummy': 'another value'}
# del : 순서쌍 삭제

del d1[5]
d1
{'a': 'some value',
 'b': [1, 2, 3, 4],
 'an integer': 7,
 'dummy': 'another value'}
# dummy 순서쌍 삭제후, ret에 value값 할당

ret = d1.pop('dummy')
ret
'another value'
d1
{'a': 'some value', 'b': [1, 2, 3, 4], 7: 'an integer'}
# key값, value값 확인

list(d1.keys()), list(d1.values())
(['a', 'b', 'an integer'], ['some value', [1, 2, 3, 4], 7])
d1.update({'b' : 'foo', 'c' : 12})
d1
{'a': 'some value', 'b': 'foo', 'an integer': 7, 'c': 12}

13 Creating dicts from sequences

# dict + zip

mapping = dict(zip(range(5), reversed(range(5))))
mapping
{0: 4, 1: 3, 2: 2, 3: 1, 4: 0}

14 Default values

words = ['apple','bat','bar','atom','book']
by_letter = {}
for word in words:
    letter = word[0]
    if letter not in by_letter:
        by_letter[letter] = [word]
    else:
        by_letter[letter].append(word)
by_letter
{'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']}

15 Valid dict key types

# 해시값 반환

hash('string'), hash((1,2,(2,3)))
(-5910375871019062728, -9209053662355515447)
# list형식은 변경 가능한 객체이므로 해시값 X

hash((1,2,[2,3]))
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

Cell In[178], line 3
      1 # list형식은 변경 가능한 객체이므로 해시값 X
----> 3 hash((1,2,[2,3]))


TypeError: unhashable type: 'list'
d = {}
d[tuple([1,2,3])] = 5
d
{(1, 2, 3): 5}

16 set

# 중복값 없이 나열

set([2,2,2,1,3,3])
{1, 2, 3}
# 중괄호로 가능

{2,2,2,1,3,3}
{1, 2, 3}
{11,22,11,22}
{11, 22}
a = {1,2,3,4,5}
b = {3,4,5,6,7,8}
# union(), | : 합집합 

a.union(b), a | b
({1, 2, 3, 4, 5, 6, 7, 8}, {1, 2, 3, 4, 5, 6, 7, 8})
# intersection, & : 교집합 

a.intersection(b), a & b
({3, 4, 5}, {3, 4, 5})
c = a.copy()
c |= b
c
{1, 2, 3, 4, 5, 6, 7, 8}
d = a.copy()
d &= b      # d에 값 다시 할당
d
{3, 4, 5}
my_data = [1,2,3,4]
my_set = {tuple(my_data)}
my_set
{(1, 2, 3, 4)}
# 부분집합, 상위집합
a_set = {1,2,3,4,5}
{1,2,3}.issubset(a_set), a_set.issuperset({1,2,3})
(True, True)
{1,2,3} == {3,2,1}
True

17 List, Set, Dict Comprehensions

strings = ['a','as','bat','car','dove','python']
[x.upper() for x in strings if len(x) >2]
['BAT', 'CAR', 'DOVE', 'PYTHON']
unique_lengths = {len(x) for x in strings}
unique_lengths
{1, 2, 3, 4, 6}
set(map(len, strings))
{1, 2, 3, 4, 6}

17.1 Quiz 3

  • 각 객체가 몇번째에 있는지 출력
loc_mapping = {val : index for index, val in enumerate(strings)}
loc_mapping
{'a': 0, 'as': 1, 'bat': 2, 'car': 3, 'dove': 4, 'python': 5}
### 루프문 써서 만들기

loc_mapping = {}
for index, val in enumerate(strings):
    loc_mapping[val] = index

loc_mapping
{'a': 0, 'as': 1, 'bat': 2, 'car': 3, 'dove': 4, 'python': 5}

17.2 Quiz 4

def multiply_by_two(x):
    return x * 2

my_list = [1,2,3,4,5]
result = list(map(multiply_by_two, my_list))

print(result)
[2, 4, 6, 8, 10]
### lambda로 간결히 사용

my_list = [1,2,3,4,5]
result = list(map(lambda x: x*2, my_list))
print(result)
[2, 4, 6, 8, 10]
result2 = list(map(lambda x: x*3,a))
result2
[3, 6, 9, 12, 15]

18 Nested list comprehensions

all_data = [['John','Emily','Michael','Mary','Steven'],
           ['Maria','Juan','Javier','Natalia','Pilar']]
### e가 한개 이상인것 추출
names_of_interest = []

for names in all_data:
    enough_es = [name for name in names if name .count('e')>=1]
    names_of_interest.extend(enough_es)

names_of_interest
['Michael', 'Steven', 'Javier']
result = [name for names in all_data for name in names
          if name.count('e') >= 2]
result
['Steven']
some_tuples = [(1,2,3),(4,5,6),(7,8,9)]
flattened = [x for tup in some_tuples for x in tup]
flattened
[1, 2, 3, 4, 5, 6, 7, 8, 9]
fruits = ['사과','바나나','수박','딸기']
for i in range(len(fruits)):
    print(i,fruits[i])
0 사과
1 바나나
2 수박
3 딸기
for i, fruit in enumerate(fruits):
    print(i,fruit)
0 사과
1 바나나
2 수박
3 딸기

[[x for x in tup] for tup in some_tuples]
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

19 Functions

a = None

def bind_a_variable():
    global a
    a = []
    
bind_a_variable()

print(a)
[]
func()
def func():
    a = []
    for i in range(5):
        a.append(i)
        
a
[]
a = []
def func():
    for i in range(5):
        a.append(i)
        
a
[]
def f():
    a=5
    b=6
    c=7
    return {'a' : a, 'b' : b, 'c' : c}

20 Functions are object

states = ['    Alabama ','Georgia!','Georgia','georgia','FlOrIda',
         'sounth   carolina##', 'West virginia?']
states
['    Alabama ',
 'Georgia!',
 'Georgia',
 'georgia',
 'FlOrIda',
 'sounth   carolina##',
 'West virginia?']
import re

def clean_strings(strings):
    result = []
    for value in strings:
        value = value.strip()            # 앞뒤 공백 제거
        value = re.sub('[!#?]','',value) # !,#,? → 공백 대체
        value = value.title()            # 문자열을 제목 형태로 (첫 대문자, 나머지 소문자) 
        result.append(value)             # 정리된 문자열 value를 result 리스트에 추가
    return result

clean_strings(states)
['Alabama',
 'Georgia',
 'Georgia',
 'Georgia',
 'Florida',
 'Sounth   Carolina',
 'West Virginia']
def remove_punctuation(value):
    return re.sub('[!#?]','',value)

clean_ops = [str.strip, remove_punctuation, str.title]

def clean_strings(strings, ops):
    result = []
    for value in strings:
        for function in ops:
            value = function(value)
        result.append(value)
    return result
clean_strings(states, clean_ops)
['Alabama',
 'Georgia',
 'Georgia',
 'Georgia',
 'Florida',
 'Sounth   Carolina',
 'West Virginia']
for x in map(remove_punctuation, states):
    print(x)
    Alabama 
Georgia
Georgia
georgia
FlOrIda
sounth   carolina
West virginia
### 첫 대문자, 나머지 소문자
'good man'.capitalize()
'Good man'
### 각 단어 첫 대문자
'good man'.title()
'Good Man'

21 Anonymous (Lambda) Functions

def apply_to_list(some_list, f):
    return [f(x) for x in some_list]

ints = [4,0,1,5,6]

apply_to_list(ints, lambda x: x*2)
[8, 0, 2, 10, 12]
strings = ['foo','card','bar','aaaa','abab']
strings
['foo', 'card', 'bar', 'aaaa', 'abab']
strings.sort(key=lambda x: len(set(x)))
strings
['aaaa', 'foo', 'abab', 'bar', 'card']
list(map(lambda x: x+10, [1,2,3,4,5,6]))
[11, 12, 13, 14, 15, 16]

22 Generators

some_dict = {'a':1, 'b':2, 'c':3}
for key in some_dict:
    print(key)
a
b
c
dict_iterator = iter(some_dict)
dict_iterator
<dict_keyiterator at 0x22ea41bfe50>
list(dict_iterator)
['a', 'b', 'c']
def squares(n=10):
    print('Generating squares from 1 to {0}'.format(n**2))
    for i in range(1, n+1):
        yield i**2
gen = squares()
gen
<generator object squares at 0x0000022EA41D5AC0>
for x in gen:
    print(x, end='')
Generating squares from 1 to 100
149162536496481100

23 Generator expressions

gen = (x **2 for x in range(100))
gen
<generator object <genexpr> at 0x0000022EA41D5EB0>
sum(x**2 for x in range(100))
dict((i, i**2) for i in range(5))
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

24 itertools module

import itertools
first_letter = lambda x: x[0]
names = ['Alan','Adam','Wes','Will','Albert','Steven']
for letter, names in itertools.groupby(names, first_letter):
    print(letter, list(names))
A ['Alan', 'Adam']
W ['Wes', 'Will']
A ['Albert']
S ['Steven']

25 Errors & Exception Handling

float('1.2345')
1.2345
float('something')
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

Cell In[125], line 1
----> 1 float('something')


ValueError: could not convert string to float: 'something'
def attempt_float(x):
    try:
        return float(x)
    except:
        return x
attempt_float('1.2345')
1.2345
attempt_float('something')
'something'
float((1,2))
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

Cell In[129], line 1
----> 1 float((1,2))


TypeError: float() argument must be a string or a number, not 'tuple'
def attempt_float(x):
    try:
        return float(x)
    except (TypeError, ValueError):
        return x
attempt_float('1.2345')
1.2345