str="hello" str="hi" 가능 str[0]='k' 는 불가능
읽기전용, 쓰기 가능을 생각하자
tuple은 못바꾸게 하려고 만든겁니다.
계산의 결과는 못바꾸게 하는 것이 좋습니다.
멀티스레드?
- thread / coroutine
- 하나 사용하고 있는 것을 다른애가 수정하는 것이 문제입니다.
- 읽는 것은 상관이 없지만, 쓰기를 해버리면 문제가 생깁니다.
- 결과가 오류가 나거나 만든 데이터가 사라지거나 합니다.
[인덱스]
: __getItem__
메서드를 호출해서 인덱스번쨰 데이터를 가져오는 것+
: 결합을 시켜서 새로운 sequence를 리턴*
: 정수와 연산해서 반복시킨 sequence를 리턴in
: 존재 여부를 리턴len(data)
: 데이터의 개수를 리턴[start:end:interval]
: 슬라이싱msg="hello World!" print(msg[::])#전체 print(msg[:-2:])#뒤에서 두번째 앞까지 print(msg[::-1])#반대로
'문자열', "문자열",
"""
여러줄
문자열
"""
- ""
안에 다른 "
할 수 없지만 '
는 가능>>,>=,<=,==,!=
연산자 사용이 가능합니다.msg="hello" msg[1]="H"
TypeError: 'str' object does not support item assignment
\n, \t, \r, \b, \f, \\, \0, \', \"
\r ,\n
: 커서를 맨앞으로 가져오고 줄바꿈 "%format.."%(데이터 나열)
: 포맷에 대이터가 설정되는데 형식을 지정할 수 있음%10d
: 10자리를 확보해서 출력함%.3f
: 소수 3자리까지(반올림)a=10 s="a="+str(a) # 문자열에서 + 는 금기시 되는 작업입니다. # 공간의 낭비가 될 수 있는 작업(두 번 이상의 작업이 필요) s="a = %d"%a #이러면 데이터가 들어가는 구조로 메모리 낭비를 줄일 수 있다.
크롤링 할 때, 메모리 낭비가 매우 심할 수 있다. 이를 막아야 한다.
"{데이터 순서: 서식}".format(데이터나열)
의 형태로도 가능s="a={0:d}".format(a)
f"문자열{변수명:서식}"
의 형태로도 가능함s=f"a={a:d}"
코딩 테스를 준비할 때는 이 클래스의 메서드는 미리 사용을 해 보는 것이 좋습니다.
코딩 테스트 -> list, str 클래스 메서드 공부를 해야 한다.
해당 메서드를 구현하는 것도 해보면 좋다.
우선 dir과 help를 통해 공부를 하자.
encode(인코딩방식=기본은 시스템인코딩)
decode(인코딩박식=시스템인코딩)
ord
함수를 사용chr
함수를 사용sys.stdin.encoding
과 sys.stdout.encoding
입니다.실습
import sys #현재 시스템의 인코딩 확인 print(sys.stdin.encoding) print(sys.stdout.encoding) #문자열을 바이트코드로 변환 print("한글".encode()) print("한글".encode().decode()) #문자 자체의 코드값 print(ord("a"), ord("한"))
이에 대한 결과
cp949 UTF-8 b'\xed\x95\x9c\xea\xb8\x80' 한글 97 54620
.
: 줄 바꿈 문자를 제외한 문자 1개
^
: 문자열의 시작과 매칭, []안에서는 반대 분자열을 의미 되지 않음
$
: 끝나는 문자열, []안에서는 그냥 $
[]
: 문자 집합을 의미
|
: 또는
()
: 정규식을 그룹으로 묶기
*
: 0회 이상의 반복
+
: 1회 이상의 반복
?
: 0이나 1회 반복
{ㅡ}
: M회 반복을 허용
{m,n}
: m회부터 n회까지
{m,}
: m회 이상
\\ 백 슬래시 문자 \d 모든 숫자 \D 숫자가 아닌 문자 \s 화이트 스페이스와 매칭 \S 화이트 스페이스가 아닌 문자와 매칭 \w 숫자 또는 문자 \W 숫자 또는 문자가 아닌 것 \b 단어의 경계 \B 단어의 경계가 아님
complie(pattern[.flags]): 정규식 인스턴스를 생성 search(pattern, string[. flags]) match(pattern, string[. flags]) split(pattern, string[. maxsplit=0]): pattern을 기준으로 분리 findall(pattern, string): pattern을 만족하는 모든 문자열을 추출 sub(pattern, repl, string[, count=0]): pattern을 찾아서 repl로 치환하는데 count는 치환횟수를 제한
import re #: 이나 |를 , 로 지환 test="lg:cns | samsung:sds" result=re.sub("[:,|]",",",test) print(result) #유효한이메일인지 검사 p=re.compile('^[a-zA-Z0-9+-\_.]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$') emails=["mhlee5894@gmail.com", "mhle29@jfc.com", "com.@mhlee", "mhlee.com@gmail"] for email in emails: print(p.match(email)!=None)
b'코드나 문자열'
하면 bytes 입니다.ndarray
가 그거야arraylist, vector
Stack, Queue, Deque
list, deque, set, dict 이걸 좀 기억해야해 코테에선
코테를 연습한다? : 문제를 보고 어떻게 해결해야 하는지 알아야 한다.
코테준비는 자료구조 준비를 먼저 해야합니다.
문자열 set, deque, dict, count, list, ..
이걸 하고 코테 들어가자
[]
[데이터나열]
list(__iter__ 구현된 인스턴스)
del list[index]
list[시작위치:종료위치]=[]
del list[시작위치:종료위치:간격]
append(데이터)
insert(인덱스, 데이터)
index(데이터)
count(값)
reverse()
remove(데이터)
: 데이터와 일치하는 첫 번째 데이터를 삭제
pop(인덱스)
: 인덱스를 생략하면 마지막 데이터를 삭제하고, 인덱스 설정을 하면 인덱스 번째 데이터를 삭제, stack에서 데이터를 꺼내는 동작이며 push는 stack에 데이터를 삽입하는 동작임
extend(__iter__ 가 구현된 객체)
list의 sort 함수를 이용하면 Timsort(Merge Sort와 Insertion Sort를 합친 Python 내부 정렬 알고리즘) 알고리즘을 이용해서 데이터를 내부적으로 정렬
sorted 함수에 list를 대입하면 정렬한 결과를 리턴
key 속성에 데이터 변환을 위한 함수를 대입하면 변환 결과를 가지고 정렬
reverse 속성에 True를 대입하면 내림차순 정렬
#list의 메서드 활용 li1=[] li2=list(range(10)) li3=["hello","world!"] #data 추가 li1.append("append data") li3.append("python") #한 개 데이터 출력 print(li3[2]) #슬라이싱 - 범위를 가지고 추출 print(li3[0:1]) #data 삭제 del li1[0] print(li1) #data 순회 for i in li3: print(i) #list 정렬 li=["Hello", "ai", "bravo","zulu", "charli"] li.sort()#오름차순 정렬 print(li) li.sort(reverse=True)#내림차순 정렬 print(li) result=sorted(li) print(result) #영문 대소문자 구분없지 정렬 li.sort(key=str.lower) print(li)
collections.deque
가 효율적record =("mino", "student", 26) # 튜플 생성 print(record) print(record[1]) # 인덱싱 가능 #record[0]="mino2" # 수정 불가능 #list와 tuple은 unpacking 가능 name, job, age=record print(job) *etc, age=record # *을 이용하면 나머지 모두를 리스트로 생성 # 1개짜리도 *을 받으면 리스트로 만든다. #swap : 2개의 데이터의 값을 치환하는 것 #python은 정말 쉽다 a=10 b=20 a,b=b,a print(a,b)
(데이터 나열)
(하나만,)
: 하나만 만들때, 뒤에 콤마를 붙어야함데이터 나열
#테이블 구조의 데이터를 생성 data=[("mino", '010'),("mino2","016")] #이름만 출력 for row in data: print(row[0]) #컬럼에 이름을 사용하는 튜플 from collections import namedtuple #자료구조 생성 - 튜플의 각 컬럼 이름 만들기 Person=namedtuple("Person",["person_name", "mobile"]) #그냥 "person", "a b" 이렇게 넣어도 상관은 없다. Persons=[Person("mino","010"),Person("mino2","016")] for person in Persons : print(person.person_name)
{데이터 나열}
set(__iter__ 가 구현된 객체)
s={"mino", "mino2","mino2","mino3"} print(s) #순서가 조금 다른데? 순서는 알 수 가 없다. #순서와는 큰 상관이 없다. s.add("mino4") print(s) for d in s: print(d)#얘도 어떤 순서로 나올지 모른다.
{key:value, key:value...}
dict이름[key]
: 키가 존재하지 않으면 KeyErrordict이름.get(key,default)
: 키가 존재하지 않으면 기본값, get으로 끄집어내자. 중요하다keys(), values(), items()
를 이용해서 key, value, (key, value) 목록을 가져올 수 있습니다.del 딕셔너리이름[key]
로 키 값을 삭제할 수 있습니다.clear()
를 하면 전체 삭제입니다.#dict 생성 dic={} #dict 데이터 추가(upsert) dic["name"]="mino" dic["job"]="student" dic["age"]=26 dic["age"]=24 #이걸로 다시 덮어씌움 print(dic) print(dic["score"])#없는 키가 들어오면 KeyError print(dic.get("score",0))#KeyError가 아닌 기본값 리턴 #순회하기 for key in dic: print(key, dic[key])
#dict를 이용한 MVC #DTO 역할을 수행하는 클래스 생성 - 최근에는 더 권장 #map을 이용하는게 더 좋을 때도 있기는 함 class DTO: def __init__(self, name="noname", tel="전화없음"): self.name=name self.tel=tel #데이터 목록 생성 data=[DTO("mino","010"), DTO("mino2","016")] #이름과 전화번호 출력 for d in data: print(d.name, d.tel) #이렇게 한다면 위에 def 부분에서 달라지면 여기도 바꿔야해 #아니면 에러가 나는걸 #dict 목록 생성 data=[{"name":"mino", "tel":"010"}, {"name":"mino2","tel":"016"}] for d in data: for key in d: print(key,":" ,d[key]) #dict로 했다면 키값을 바꿔도 에러가 안나지 왜냐? #키 이름을 쓰진 않았기 때문이다. #근데 dict하면 코드셋 안보여서 프로그래밍하기 어려워짐
#이차원 배열 대신에 dict 사용 babamba=["ba","bamba"] banana=["ba","nana"] apple=["ap","ple"] #mine=[babamba,banana,apple]#list의 list #이거 매우 별로다. #list는 인덱스를 통해 접근하고, dict는 key를 통해 접근한다. #for my in mine: #이렇게 쓰면 바밤바랑 바나나는 못쓴다. for idx, my in enumerate(mine): # enumerate는 인덱스와 데이터를 튜플로 리턴합니다. if idx==0: print("바밤바", end='\t') else: print("바나나", end='\t') for word in my: print(word, end='\t') #여기서 my가 늘어나면 문제가 발생함 #인덱스가 변화하게 된다면 어려워진다. mine=[{"name":"바밤바","data":babamba}, {"name":"바나나","data":banana},{"name":"사과","data":apple}] for dic in mine: print(dic.get("name"),end=":") for word in dic.get("data"): print(word,end='\t') print()
li=list(range(10)) #li의 모든 데이터를 제곱한 list를 생성 result=[] #일반 반복문 # for i in li: # result.append(i*i) #map 함수를 이용해보자 result=list(map(lambda i : i*i,li)) print(result) #list comprehension #[연산식 순회할문장] result=[i*i for i in li] print(result) #for 2r개 사용하기 li1=[1,2,3] li2=[4,5,6] result1=[x*y for x in li1 for y in li2] print(result1)
#for 와 if 사용 가능 - filtering singers=["윤하","아이유","태연","다린"] #글자 수가 2인 데이터만 추출 result=list(filter(lambda x:len(x)==2, singers)) #위에 필터가 더 느리다. #함수는 항상 별도의 메모리 공간을 받아서 작업을 수행하고 #돌아와야 한다. print(result) result1=[x for x in singers if len(x)==2] print(result1) #윤하만 골라내보자. result_Y=[x for x in singers if len(x)==2 and x>"아" and x<"타"] #조건을 길게 할 수 있다. print(result_Y) #if-else for 활용 #3글자 이상은 그대로, 나머지는 _를 추가 result_T=[x if len(x)>=3 else x+"_" for x in singers] print(result_T)
함수를 안만든 list comprehension으로 한 것이 더 빠르다.
이거 진짜진짜진짜진짜 연습 많이 해야합니다.
from collections import Counter data=["한식","한식","중식","양식","일식","양식","한식"] counter=Counter(data) print(dict(counter)) #한가지 데이터 파악 print(counter["한식"]) #상위 2개만 추출해보자. print(counter.most_common(2))
{'한식': 3, '중식': 1, '양식': 2, '일식': 1}
3
[('한식', 3), ('양식', 2)]
#튜플의 목록 data=[("Apple",3),("Apple",2),("Apple",1),("Orange",1), ("Banana",6),("Orange",3)] counter=Counter() #구조를 분해해야겠는걸? #데이터가 등장한 합계 구하기 for name, count in data: counter[name]+=count print(counter) #데이터가 등장한 횟수를 구해보기 counter=Counter() for name, count in data: counter[name]+=1 print(counter)
Counter({'Apple': 6, 'Banana': 6, 'Orange': 4})
Counter({'Apple': 3, 'Orange': 2, 'Banana': 1})
조합형 이터레이터 함수
- combinations(iterable, r) :
- iterable에서 원소 개수가 r개인 조합 뽑기- combinations_with_replacement(iterable,r):
- iterable에서 원소 개수가 r개인 중복 조합뽑기- product(*iterables, repeat=1):
- 여러 iterable의 데카르트곱 리턴- permutations(iterable,r=None):
- iterable에서 원소 개수가 r개인 순열 뽑기
https://docs.python.org/ko/3/library/itertools.html
이거 보고 좀 공부를 하자.
def div(x): return 10/x print(div(20)) print(div(0)) print("프로그램 종료")
이러면 예외가 발생해서 중간에 프로그램이 중단됨
try: 예외가 발생할 가능성이 있는 구문 except : 예외가 발생했을 때 수행할 구문
def div(x): return 10/x try: print(div(20)) print(div(0)) except : print("예외 발생!") print("프로그램 종료")
이렇게 한다면 예외가 발생해도 프로그램이 멈추지 않습니다.
크롤링을 할 때, 데이터의 링크를 찾아가다 보면 데이터의 링크는 있지만, 데이터가 없는 경우가 발생할 수 있는데, 그런 경우에는 예외처리를 하지 않으면 크롤링 도주에 종료되어버릴 수 있기 때문에 예외 처리 구문을 사용해서 링크는 있는데 데이터가 삭제된 경우에는 다음 데이터를 수집할 수 있도록 만들어 주는 것이 좋습니다.
python에서는 while for 다음에 else를 적을 수 있음, 이는 반복문이 정삭적으로 수행되었을 때 적을 수 있다는 것임 이것으로 예외발생을 확인할 수 있음
반드시 try-except를 할 때가 있어요.
- 내가 만들지 않은 자원을 사용할 때
- 내가 만들지 않았기에 있는지 없는지 보장을 못함
- file-handling : 생성, 읽기 권한 os가 가짐
- network : 다른 컴퓨터가 켜져있는지 모름
- db : db 서버는 별도로 둡니다. (결국 이것도 네트워크)