-
파이썬 기초와 Ipython, jupyter notebookPython 2023. 10. 31. 17:42
C:\Users\Desktop\project\basic>python hello.py hello.py __main__ C:\Users\Desktop\project\basic>ipython In [1]: %run hello.py hello.py __main__ In [2]: an_apple = 27 In [3]: an_example = 42
an 입력하고 tap 키 누르면 자동 완성 기능 제공
자기관찰(인트로스펙션 introspection)
In [3]: b = [1, 2, 3] In [4]: b? Type: list String form: [1, 2, 3] Length: 3 Docstring: Built-in mutable sequence. If no argument is given, the constructor creates a new empty list. The argument must be an iterable if specified. In [5]: print? Signature: print(*args, sep=' ', end='\n', file=None, flush=False) Docstring: Prints the values to a stream, or to sys.stdout by default. sep string inserted between values, default a space. end string appended after the last value, default a newline. file a file-like object (stream); defaults to the current sys.stdout. flush whether to forcibly flush the stream. Type: builtin_function_or_method
변수 이름 앞이나 뒤에 물음표를 붙이면 그 객체에 대한 일반 정보 출력
In [7]: def add_numbers(a, b): ...: """ ...: Add two numbers together ...: Returns ...: ------ ...: the sumL type of arguments ...: """ ...: return a + b ...: In [8]: add_numbers? Signature: add_numbers(a, b) Docstring: Add two numbers together Returns ------ the sumL type of arguments File: c:\users\desktop\project\basic\<ipython-input-7-004085b61198> Type: function
별표(*)로 문자열을 둘러싸게 되면 해당 문자열이 포함된 모든 이름을 보여 줌
In [9]: import numpy as np In [10]: np.*load*? np.__loader__ np.load np.loadtxt
In [11]: a = b In [12]: a.append(4) In [13]: a Out[13]: [1, 2, 3, 4] In [14]: b Out[14]: [1, 2, 3, 4]
변수에 값을 할당하는 것은 한 이름이 하나의 객체로 연결되므로 바인딩이라고 부름
값이 할당된 변수 이름은 때때로 종속 변수라고 부르기도 함
In [15]: def append_element(some_list, element): ...: some_list.append(element) ...: In [16]: data = [1, 2, 3] In [17]: append_element(data, 4) In [18]: data Out[18]: [1, 2, 3, 4]
In [23]: a = 4.5 In [24]: b = 2 In [25]: # 문자열 출력 형식을 지정한다. 나중에 자세히 살펴본다 In [26]: print('a is {}, b is {}'.format(type(a), type(b))) a is <class 'float'>, b is <class 'int'>
모듈 import
C:\Users\Desktop\project\basic>copy con some_module.py # some_module.py PI = 3.14159 def f(x): return x + 2 def g(a, b): return a + b ^Z # 코드 입력 후 ctrl + Z 1개 파일이 복사되었습니다.
In [2]: import some_module In [3]: result = some_module.f(5) In [4]: In [4]: pi = some_module.PI In [5]: pi Out[5]: 3.14159 In [6]: # 또는 In [7]: from some_module import g, PI In [8]: result = g(5, PI) In [9]: result Out[9]: 8.14159
문자열
In [33]: animals = ''' ...: cat ...: dog ...: fish ...: ''' In [34]: animals Out[34]: '\ncat\ndog\nfish\n' In [35]: animals.count('\n') Out[35]: 4
In [36]: a = 'this is a string' In [37]: a[10] = 'f' --------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[37], line 1 ----> 1 a[10] = 'f' TypeError: 'str' object does not support item assignment
파이썬의 문자열은 변경이 불가능
> replace 같은 메서드를 사용해 변경된 새로운 문자열을 생성해야 함
In [38]: b = a.replace('string', 'longer string') In [39]: b Out[39]: 'this is a longer string' In [40]: a Out[40]: 'this is a string'
작업 이후 변수 a는 변경되지 않음
역슬래시(\)는 이스케이프 문자로 개행 문자 \n이나 유니코드 문자 같은 특수한 목적의 문자를 나타내기 위해 사용
역슬래시를 나타내려면 역슬래시 자체를 이스케이프해야 함
In [54]: s = '12\34' In [55]: s Out[55]: '12\x1c' In [56]: s = '12\\34' In [57]: s Out[57]: '12\\34'
특수 문자 없이 역슬래시가 많이 포함된 문자열 나타낼 때, 혹은 특수문자를 그대로 나타내도록 할 때
In [52]: s = r'this\has\no\special\characters' In [53]: s Out[53]: 'this\\has\\no\\special\\characters'
코드 앞에 r을 붙임
In [58]: template = '{0:.2f} {1:s} are worth US${2:d}'
{0:.2f}는 첫 번째 인수를 소수점 아래 두 자리까지만 표시하는 부동소수점 형태로 출력하라는 의미
{1:s}는 두 번째 인수를 문자열로 포맷하라는 의미
{2:d}는 세 번째 인수를 정수로 포맷하라는 의미
In [59]: template.format(88.46, 'Argentine Pesos', 1) Out[59]: '88.46 Argentine Pesos are worth US$1'
포맷 매개변수를 통해 대치하고 싶은 인수를 format 메서드에 전달
파이썬 3.6부터 문자열 포맷을 편리하게 지정할 수 있는 f-string 기능 추가됨
f-string을 만들려면 문자열을 감싸는 따옴표 앞에 f를 붙이면 됨
In [60]: amount = 10 In [61]: rate = 88.46 In [62]: currency = 'Pesos' In [63]: result = f'{amount} {currency} is worth US${amount / rate}' In [64]: f'{amount} {currency} is worth US${amount / rate:.2f}' Out[64]: '10 Pesos is worth US$0.11'
위 문자열 템플릿과 같은 방법으로 각 표현식 뒤에 포맷 지정 가능
정렬
In [34]: a = [7, 2, 5, 1, 3] In [35]: a.sort() In [36]: a Out[36]: [1, 2, 3, 5, 7] In [37]: b = ['saw', 'small', 'He', 'foxes', 'six'] In [38]: b.sort(key=len) In [39]: b Out[39]: ['He', 'saw', 'six', 'small', 'foxes']
sort는 몇 가지 옵션을 제공하는데 그중 하나는 사용할 값을 반환하는 함수
슬라이싱
# 원하는 크기만큼 자르기 In [40]: seq = [7, 2, 3, 7, 5, 6, 0, 1] In [41]: seq[1:5] Out[41]: [2, 3, 7, 5] # 다른 순차 자료형을 대입할 수 O In [42]: seq[3:5] = [6, 3] In [43]: seq Out[43]: [7, 2, 3, 6, 3, 6, 0, 1]
색인의 시작(start) 위치에 있는 값은 포함, 끝(stop)은 포함 x
슬라이싱 결과의 개수는 stop - start
In [44]: seq[-4:] Out[44]: [3, 6, 0, 1] In [45]: seq[-6:-2] Out[45]: [3, 6, 3, 6]
음수 색인은 순차 자료형의 끝에서부터 위치를 나타냄
In [46]: seq[::2] Out[46]: [7, 3, 3, 0] In [47]: seq[::-1] Out[47]: [1, 0, 6, 3, 6, 3, 2, 7]
두 번째 콜론 다음에 간격(step) 지정할 수 있음
값으로 -1을 사용하면 리스트나 튜플을 역순으로 반환
딕셔너리
In [49]: empty_dict = {} In [50]: d1 = {'a': 'some value', 'b': [1, 2, 3, 4]} In [51]: d1 Out[51]: {'a': 'some value', 'b': [1, 2, 3, 4]} In [52]: d1[7] = 'an integer' In [53]: d1 Out[53]: {'a': 'some value', 'b': [1, 2, 3, 4], 7: 'an integer'} In [54]: d1['b'] Out[54]: [1, 2, 3, 4] In [55]: 'b' in d1 Out[55]: True In [56]: d1[[10, 20]] = [100, 200] --------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[56], line 1 ----> 1 d1[[10, 20]] = [100, 200] TypeError: unhashable type: 'list'
다른 프로그래밍 언어에서는 해시 맵 또는 연관 배열(associative array)로 알려져 있음 키-값 쌍을 저장
리스트는 키로 사용할 수 없음
del 예약어나 pop 메서드(값을 반환함과 동시에 해당 키 삭제)를 통해 딕셔너리 값을 삭제할 수 있
In [57]: d1[5] = 'some value' In [58]: d1 Out[58]: {'a': 'some value', 'b': [1, 2, 3, 4], 7: 'an integer', 5: 'some value'} In [59]: d1['dummy'] = 'another value' In [60]: d1 Out[60]: {'a': 'some value', 'b': [1, 2, 3, 4], 7: 'an integer', 5: 'some value', 'dummy': 'another value'} In [61]: del d1[5] In [62]: d1 Out[62]: {'a': 'some value', 'b': [1, 2, 3, 4], 7: 'an integer', 'dummy': 'another value'} In [63]: ret = d1.pop('dummy') In [64]: ret Out[64]: 'another value' In [65]: d1 Out[65]: {'a': 'some value', 'b': [1, 2, 3, 4], 7: 'an integer'}
keys와 values 메서드는 각각 키와 값이 담긴 이터레이터 반환, 키의 순서는 삽입 순서에 따라 다름
이러한 함수는 키와 값을 각각 동일한 순서로 출력
In [66]: list(d1.keys()) Out[66]: ['a', 'b', 7] In [67]: list(d1.values()) Out[67]: ['some value', [1, 2, 3, 4], 'an integer']
키와 값에 대해 반복 작업을 해야 하는 경우 items 메서드를 사용하면 키-값 쌍을 갖는 튜플로 사용할 수 있음
In [68]: list(d1.items()) Out[68]: [('a', 'some value'), ('b', [1, 2, 3, 4]), (7, 'an integer')]
update 메서드를 사용하면 하나의 딕셔너리를 다른 딕셔너리와 합칠 수 있음
In [69]: d1.update({'b': 'foo', 'c': 12}) In [70]: d1 Out[70]: {'a': 'some value', 'b': 'foo', 7: 'an integer', 'c': 12}
이미 존재하는 키에 대해 update를 호출하면 이전 값은 사라짐
순차 자료형에서 딕셔너리 생성
In [71]: tuples = zip(range(5), reversed(range(5))) In [72]: tuples Out[72]: <zip at 0x2287a0e2780> In [73]: mapping = dict(tuples) In [74]: mapping Out[74]: {0: 4, 1: 3, 2: 2, 3: 1, 4: 0}
본질적으로 딕셔너리는 두 개짜리 튜플로 구성됨
dict 함수가 두 개짜리 튜플의 리스트를 인수로 받아 딕셔너리를 생성
(딕셔너리가 만들어지는 과정)
기본값
In [75]: words = ['apple', 'bat', 'bar', 'atom', 'book'] In [76]: by_letter = {} In [77]: for word in words: ...: letter = word[0] ...: if letter not in by_letter: ...: by_letter[letter] = [word] ...: else: ...: by_letter[letter].append(word) ...: In [78]: by_letter Out[78]: {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']}
setdefault 메서드 사용 목적
In [79]: by_letter = {} In [80]: for word in words: ...: letter = word[0] ...: by_letter.setdefault(letter, []).append(word) ...: In [81]: by_letter Out[81]: {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']}
내장 collections 모듈에는 위 과정을 좀 더 쉽게 만드는 defaultdict 클래스가 있음
자료형 혹은 딕셔너리의 각 슬롯에 담길 기본값을 생성하는 함수를 넘겨 딕셔너리 생성
In [85]: from collections import defaultdict In [86]: for word in words: ...: by_letter[word[0]].append(word) ...: In [87]: by_letter Out[87]: defaultdict(list, {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']})
In [91]: keys = ['a', 'b', 'c', 'd'] In [92]: x = dict.fromkeys(keys, 0) In [93]: x Out[93]: {'a': 0, 'b': 0, 'c': 0, 'd': 0} In [94]: x['z'] --------------------------------------------------------------------------- KeyError Traceback (most recent call last) Cell In[94], line 1 ----> 1 x['z'] KeyError: 'z' In [95]: from collections import defaultdict In [96]: y = defaultdict(int) In [97]: y['z'] Out[97]: 0 In [98]: int() Out[98]: 0 In [99]: z = defaultdict(lambda: 'python') In [100]: z['a'] Out[100]: 'python' In [101]: z[0] Out[101]: 'python'
유효한 딕셔너리 키
딕셔너리의 값으로는 어떤 파이썬 객체든 가능하지만 키는 스칼라 자료형(정수, 실수, 문자열)이나 튜플(튜플에 저장된 값 또한 바뀌지 않는 객체여야 함)처럼 값이 바뀌지 않는 객체만 가능
기술적으로는 해시가 가능(hashability)해야 함, 어떤 객체가 해시가 가능한지는(딕셔너리의 키로 사용할 수 있는지) hash 함수를 사용해 검사할 수 있음
In [103]: hash('string') Out[103]: -3594434936365532107 In [104]: hash((1, 2, (2, 3))) Out[104]: -9209053662355515447 In [105]: hash((1, 2, [2, 3])) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[105], line 1 ----> 1 hash((1, 2, [2, 3])) TypeError: unhashable type: 'list'
비가역으로 해시 > 원래 넣었던 객체는 불가능, 길이는 모두 같음
집합
# 집합 In [106]: set([2, 2, 2, 1, 3, 3]) Out[106]: {1, 2, 3} In [107]: a = {1, 2, 3, 4, 5} In [108]: b = {3, 4, 5, 6, 7, 8} # 합집합 In [109]: a.union(b) Out[109]: {1, 2, 3, 4, 5, 6, 7, 8} In [110]: a|b Out[110]: {1, 2, 3, 4, 5, 6, 7, 8} # 교집합 In [111]: a.intersection(b) Out[111]: {3, 4, 5} In [112]: a & b Out[112]: {3, 4, 5} # 부분집합, 상위집합 In [113]: a_set = {1, 2, 3, 4, 5} In [114]: {1, 2, 3}.issubset(a_set) Out[114]: True In [115]: a_set.issuperset({1, 2, 3}) Out[115]: True # 집합의 내용이 같다면 두 집합은 동일(순서가 없기 때문) # 리스트나 튜플은 False In [116]: {1, 2, 3} == {3, 2, 1} Out[116]: True
딕셔너리도 순서가 없기 때문에 셸 창에 {1: 'cat', 2: 'dog'} == {2: 'dog', 1: 'cat'} 입력했을 때 True 출력
내장 순차 자료형 함수
1. enumerate
순차 자료형에서 현재 아이템의 index를 함께 추적할 때 사용
In [117]: a = [38, 21, 53, 62, 19] In [118]: for i, v in enumerate(a): ...: print(i, v) ...: 0 38 1 21 2 53 3 62 4 19
2. sorted
정렬된 새로운 순차 자료형 반환
In [119]: sorted([7, 1, 2, 6, 0, 3, 2]) Out[119]: [0, 1, 2, 2, 3, 6, 7] In [120]: sorted('horse race') Out[120]: [' ', 'a', 'c', 'e', 'e', 'h', 'o', 'r', 'r', 's'] In [194]: a = [7, 1, 2, 6, 0, 3, 2] In [195]: sorted(a) Out[195]: [0, 1, 2, 2, 3, 6, 7] In [196]: a Out[196]: [7, 1, 2, 6, 0, 3, 2] In [197]: a.sort() In [198]: a Out[198]: [0, 1, 2, 2, 3, 6, 7]
3. zip
여러 개의 리스트나 튜플 또는 다른 순차 자료형을 서로 짝지어 튜플 리스트 생성
In [126]: seq1 = ['foo', 'bar', 'baz'] In [127]: seq2 = ['one', 'two', 'three'] In [128]: zipped = zip(seq1, seq2) In [129]: list(zipped) Out[129]: [('foo', 'one'), ('bar', 'two'), ('baz', 'three')] In [130]: seq3 = [False, True] In [131]: list(zip(seq1, seq2, seq3)) Out[131]: [('foo', 'one', False), ('bar', 'two', True)] In [132]: for index, (a, b) in enumerate(zip(seq1, seq2)): ...: print(f'{index}: {a}, {b}') ...: 0: foo, one 1: bar, two 2: baz, three In [133]: a Out[133]: 'baz' In [134]: b Out[134]: 'three'
리스트, 집합, 딕셔너리 표기
리스트 표기법
In [135]: strings = ['a', 'as', 'bat', 'car', 'dove', 'python'] In [136]: [x.upper() for x in strings if len(x) > 2] Out[136]: ['BAT', 'CAR', 'DOVE', 'PYTHON']
필터 조건 생략 가능, 문자열 리스트가 있다면 위 코드처럼 문자열의 길이가 2 이하인 문자열은 제외하고 나머지를 대문자로 변환 가능
집합과 딕셔너리도 동일한 방식 적용 가능
리스트 내 문자열들의 길이를 담고 있는 집합을 생성하려면 집합 표기법을 이용해 다음과 같이 처리
In [141]: unique_lengths = {len(x) for x in strings} In [142]: unique_lengths Out[142]: {1, 2, 3, 4, 6}
map 함수를 이용해 함수적으로도 표현 가능
In [143]: set(map(len, strings)) Out[143]: {1, 2, 3, 4, 6}
딕셔너리 표기법 예제: 리스트에서 문자열의 위치를 담고 있는 딕셔너리 생성
In [144]: loc_mapping = {value: index for index, value in enumerate(strings)} In [145]: loc_mapping Out[145]: {'a': 0, 'as': 1, 'bat': 2, 'car': 3, 'dove': 4, 'python': 5}
중첩된 리스트 표기법
각 이름에서 알파벳 a가 두 개 이상 포함된 이름의 리스트 구한다고 했을 때 다음과 같은 반복문으로 리스트를 구할 수 있음
In [146]: all_data = [['John', 'Emily', 'Michael', 'Mary', 'Stevev'], ['Maria', 'Juan', 'Javier', 'Natalia', 'Pilar']] In [147]: names_of_interest = [] In [148]: for names in all_data: ...: enough_as = [name for name in names if name.count('a') >= 2] ...: names_of_interest.extend(enough_as) ...: In [149]: names_of_interest Out[149]: ['Maria', 'Natalia']
위 코드 전체를 중첩된 리스트 표기법을 이용해 한 번에 구현할 수 있음
In [151]: result = [name for names in all_data for name in names ...: if name.count('a') >= 2] In [152]: In [152]: result Out[152]: ['Maria', 'Natalia']
리스트 표기법에서 for 부분은 중첩의 순서에 따라 나열되며 필터 조건은 끝에 위치함
숫자 튜플이 담긴 리스트를 단순한 리스트로 변환하는 예제
In [153]: some_tuples = [(1, 2, 3), (4, 5, 6), (7, 8, 9)] In [154]: flattened = [x for tup in some_tuples for x in tup] In [155]: flattened Out[155]: [1, 2, 3, 4, 5, 6, 7, 8, 9]
함수
In [157]: def my_function(x, y): ...: return x + y ...: In [158]: my_function(1, 2) Out[158]: 3 In [159]: result = my_function(1, 2) In [160]: result Out[160]: 3
함수 블록이 끝날 때까지 return 문이 없다면 자동으로 None이 반환됨
In [161]: def function_without_return(x): ...: print(x) ...: In [162]: result = function_without_return('hello!') hello! In [163]: print(result) None
각 함수는 여러 개의 위치 인수와 키워드 인수를 받을 수 있음
키워드 인수는 기본값이나 선택적인 인수로 흔히 사용됨
In [164]: def my_function2(x, y, z=1.5): ...: if z > 1: ...: return z * (x + y) ...: else: ...: return z / (x + y) ...: In [165]: my_function2(5, 6, z=0.7) Out[165]: 0.06363636363636363 In [166]: my_function2(3.14, 7, z=3.5) Out[166]: 35.49 In [167]: my_function2(10, 20) Out[167]: 45.0
키워드 인수는 선택 사항이지만 함수를 호출할 때 위치 인수는 반드시 지정해야 함
함수의 키워드 인수는 항상 위치 인수 다음에 와야 한다는 규칙이 있음
네임스페이스, 스코프, 지역함수
함수는 전역(global)과 지역(local), 두 가지 스코프(scope)에서 변수를 참조
변수의 스코프를 설명하는 다른 용어로 네임스페이스가 있음, 함수에서 선언된 변수는 기본적으로 모두 지역 네임스페이스에 속함
In [168]: def func(): ...: a = [] ...: for i in range(5): ...: a.append(i) ...: In [169]: def func(): ...: a = [] ...: for i in range(5): ...: a.append(i) ...: print(a) ...: In [170]: func() [0, 1, 2, 3, 4] In [171]: print(a) baz In [172]: a = [] In [173]: def func(): ...: for i in range(5): ...: a.append(i) ...: In [174]: func() In [175]: a Out[175]: [0, 1, 2, 3, 4] In [176]: func() In [177]: a Out[177]: [0, 1, 2, 3, 4, 0, 1, 2, 3, 4] In [178]: a = None In [179]: def bind_a_variable(): ...: global a ...: a = [] ...: bind_a_variable() In [180]: In [180]: print(a) [] In [181]: print(a.append('apple')) None In [182]: a Out[182]: ['apple']
global 예약어의 사용은 권장되지 않음
여러 값 반환
In [183]: def f(): ...: a = 5 ...: b = 6 ...: c = 7 ...: return a, b, c ...: In [184]: a, b, c = f() In [185]: f() Out[185]: (5, 6, 7) In [187]: x Out[187]: {'a': 0, 'b': 0, 'c': 0, 'd': 0} In [188]: x, y, z = (5, 6, 7) In [189]: x Out[189]: 5 In [190]: def f(): ...: a = 5 ...: b = 6 ...: c = 7 ...: return {'a': a, 'b': b, 'c': c} ...: In [191]: result = f() In [192]: result Out[192]: {'a': 5, 'b': 6, 'c': 7}
경우에 따라 딕셔너리를 반환하는 방식이 더 유용할 수 있음
'Python' 카테고리의 다른 글
판다스 (0) 2023.11.14 넘파이 기본: 배열과 벡터 연산 (0) 2023.11.07 웹의 데이터로 그래프 그리기 (0) 2023.10.31 모듈과 패키지 만들기 (0) 2023.10.30 모듈과 패키지 사용 (0) 2023.10.30