파일을 생성하는 방법은 2가지가 있다.
# 첫번째 방법
# open(파일이름, 파일모드)
f = open('python.txt', 'w') # 파일모드 : r, w, a, r+,
f.write('hello world')
f.close()
close()를 하지 않으면 메모리 계속 살아있으니 조심해야 한다.
# 두번째 방법
with open('test.txt', 'w') as f:
f.write('hello world!')
두번째 방법은 close가 필요 없어서 위처럼 쓰도록 하자.
예시를 한번 보자.
db_data = [
{
"_id": "7f5440ab-7e2f-4a42-Be13-89987fa65b32",
"index": "1",
"name": "등윤상",
"email": "user-qe89s09@ut.io",
"phone": "010-3542-7711",
"country": "키리바시",
"address": "방학로 74-9",
"job": "일러스트레이터"
},
{
"_id": "b4f7ade0-38bb-4e6f-B94a-18af1426eb30",
"index": "2",
"name": "노동규",
"email": "user-nyr5mqw@ornare.com",
"phone": "010-9743-6320",
"country": "베냉",
"address": "남부순환로 54-6",
"job": "애완동물미용사"
},
{
"_id": "5d788255-8d5e-4f03-B446-dbac6a147e37",
"index": "3",
"name": "경진아",
"email": "user-n7pey4v@Etiam.biz",
"phone": "010-4049-8718",
"country": "아르메니아",
"address": "강남대로 87-5",
"job": "플로리스트"
},
{
"_id": "083efce4-17ed-4e9f-Ad7c-f9aa0ac6cb79",
"index": "4",
"name": "복소유",
"email": "user-ohaz2is@nibh.biz",
"phone": "010-3400-5945",
"country": "페루",
"address": "양산로 78-1",
"job": "응급구조사"
},
{
"_id": "d54ce0fa-c025-4af6-Cd9a-b9d10aa8be5a",
"index": "5",
"name": "화예빈",
"email": "user-mnkpdlp@vel.net",
"phone": "010-3120-8720",
"country": "허드 및 맥도널드 제도",
"address": "한남대로 6-2",
"job": "전문의사"
}
]
위와 같은 db_data라는 json형식의 데이터가 있다.
list(map(lambda x: x['name'], db_data))
# ['등윤상', '노동규', '경진아', '복소유', '화예빈']
for i, name in enumerate(map(lambda x: x['name'], db_data)):
with open(f'{name}_info.txt', 'w') as f:
f.write(str(db_data[i]))
db_data에서 'name'부분만 따와서 그 이름으로 파일을 만드는 코드이다. 이때, map을 list로 묶지 않고 반복문 돌리는 것을 추천한다.
with open('data.csv', 'w') as f:
s = '아이디,인덱스,이름,이메일,휴대폰,나라,주소,직업\n'
for i in db_data:
s += f'{i["_id"]},{i["index"]},{i["name"]},{i["email"]},{i["phone"]},{i["country"]},{i["address"]},{i["job"]}\n'
f.write(s)
data.csv라는 파일이 없으면 만들고 db_data에 있는 내용을 반복하며 추가하는 코드이다. f.write()로 내용을 추가했다.
for item in db_data:
s += f'''
<tr>
<td>{item["_id"]}</td>
<td>{item["index"]}</td>
<td>{item["name"]}</td>
<td>{item["email"]}</td>
<td>{item["phone"]}</td>
<td>{item["country"]}</td>
<td>{item["address"]}</td>
<td>{item["job"]}</td>
</tr>
'''
s += '</table>'
with open('test.html', 'w') as f:
f.write(s)
위와 같은 방식으로 html형식의 데이터를 만들 수도 있다.
실무에서 비트연산을 하는 경우가 거의 없지만 알고리즘 테스트에서 간혹 나오므로 알아두자.
# 10진법
# 1542 == 1 * (10**3) + 5 * (10**2) + 4 * (10**1) + 2 * (10**0)
# 0123456789 10
# 16진법
# 1542 == 1 * (16**3) + 5 * (16**2) + 4 * (16**1) + 2 * (16**0)
# 0123456789abcdef 10
# 8진법
# 1542 == 1 * (8**3) + 5 * (8**2) + 4 * (8**1) + 2 * (8**0)
# 01234567 10
# 01 10
# 3 & 9
# and연산은 곱하기
# 0011
# 1001
# ----
# 0001
# 3 | 9
# or연산은 더하기
# 0011
# 1001
# ----
# 1011 => 11
name = '이호준'
age = 10
'제 이름은 %s이고 제 나이는 %d입니다.'%(name, age) # % 용법
'제 이름은 {}이고 제 나이는 {}입니다'.format(name, age) # format 용법(이 문법도 아직 많이 사용한다.)
f'제 이름은 {name}이고 제 나이는 {age}입니다'
f-string을 권고한다고 한다. 추가로, print문 안에 수식을 많이 넣지 않는게 좋다!
one_length = 5.343123123
print(f'{one_length} 입니다.')
print(f'{one_length:.1f} 입니다.')
.1f등의 문법으로 소수점을 짤라서 보여줄 수 있다.
age = 100
print('당신의 나이는 [{:^15}]세'.format(22))
# 당신의 나이는 [ 22 ]세
로그 출력할때 위처럼 하면 중간에 공백을 만들어 출력할 수 있다. 이거는 많이 사용한다고 한다.
# 출력에 중괄호를 넣고싶다면 중괄호 2개
print(f"My set is {{1, 2, 3}}.") # 출력: My set is {1, 2, 3}.
중괄호 2개로 중괄호 출력이 가능하다.
# 중괄호 3개를 사용하면 변수까지 출력할 수 있다.
x = 10
print(f"My set is {{{x}}}.") # 출력: My set is {10}.
print(f"My set is {{{{x}}}}.")
# My set is {10}.
# My set is {{x}}.
기존 시퀀스(sequence), 이터러블(iterable), 또는 다른 표현식들로부터 새로운 시퀀스를 생성하는 간결하고 가독성 있는 방법
# 예시 1
even_squares_set = {x**2 for x in range(10) if x % 2 == 0}
even_squares_set
# 예시 2
even_squares_gen = [x**2 for x in range(10) if x % 2 == 0]
even_squares_gen
리스트 컴프리헨션은 c로 구현되어 있어 for문만 쓰는거보다 훨씬 빠르다
위의 예제에서 볼 수 있듯이 손님1을 처리하고, 손님2를 처리하고 손님3을 처리하는 것을 말한다. 즉, 특정 작업이 완료될 때까지 프로그램이 기다리는 방식이다. 보통의 경우는 동기 프로그래밍이다.
동기프로그래밍과는 다르게 동시에 여러 작업을 진행할 수 있다. 이때, 이벤트 루프와 콜백 함수 등을 활용하여 작업을 관리한다. 함수에 async라는 키워드를 붙여 비동기 함수(코루틴)을 만들어 사용한다고 한다.
유효성 검증, 문자열 처리, 코딩테스트에 자주 등장한다고 한다
hello world
Hello
^hello -> hello로 시작하는 문자열(앞에 다른 문자 없음)
hello$ -> hello로 끝나는 문자열(뒤에 다른 문자 없음)
^hello$ -> hello로 시작하고 hello로 끝나는 문자열(hello만 들어있는)
. -> 줄바꿈 문자(\n)을 제외한 모든 문자
..... -> 5글자(.의 개수) 이상인 문자열을 5글자씩 끊어서 반환
h[eao]llo -> h + e or a or o + llo인 문자열
.[eao]llo -> 아무 문자 1개(\n제외) + e or a or o + llo인 문자열
^h[eao]llo$ -> h로 반드시 시작(앞에 다른 문자 없음) + e or a or o + llo로 반드시 끝나는 문자열(뒤에 다른 문자 없음)
h[a-zA-Z0-9]llo -> h로 반드시 시작(앞에 다른 문자 없음) + 알파벳 대소문자 or 0-9숫자 + llo
h[a-zA-Z]llo -> h로 시작 + 알파벳 대소문자 + llo
010-[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9] -> 010 + -(하이푼) + 숫자 4자리 + -(하이푼) + 숫자4자리
010.[0-9][0-9][0-9][0-9].[0-9][0-9][0-9][0-9] -> 010 + 아무 문자 1개(\n제외) + 숫자 4자리 + -(하이푼) + 숫자4자리
010[- .][0-9][0-9][0-9][0-9][- .][0-9][0-9][0-9][0-9] -> 010 + - or 공백 or . + 숫자 4자리 + - or 공백 or . + 숫자4자리
[^a-zA-Z0-9]: 나머지 문자열을 찾음 #, ^는 대괄호 안에서는 '부정' -> 알파벳이 아니고 숫자가 아닌 문자열
* : 앞에 있는 문자가 0개 이상 = ({0,})
+ : 앞에 있는 문자가 1개 이상 = ({1,})
? : 앞에 있는 문자가 0개 ~ 1개 = ({0,1})
010[- .]?[0-9][0-9][0-9][0-9][- .]?[0-9][0-9][0-9][0-9] -> 010 + - or 공백 or . + ?(앞에 문자가 있어도 되고 없어도 됨) + 숫자 4자리 + - or 공백 or . + ?(앞에 문자가 있어도 되고 없어도 됨) + 숫자 4자리
{3} : 3개
{3,} : 3개 이상
{1,3} : 1개 ~ 3개
010[- .]?[0-9]{4}[- .]?[0-9]{4} -> 010 + - or 공백 or . + ?(앞에 문자가 있어도 되고 없어도 됨) + 0-9숫자 4개 + - or 공백 or . + ?(앞에 문자가 있어도 되고 없어도 됨) + 숫자 4개
[0-9]{3}[-.* ][0-9]{4}[-.* ][0-9]{4} -> 0-9숫자 3개 + - or . or * or 공백 + 숫자 4개 + - or . or * or 공백 + 숫자 4개
수량자(, +, {n,} 등) 뒤에 붙는 ?
는 해당 수량자를 비탐욕적
(non-greedy) 또는 lazy으로 만든다. 기본적으로 수량자는 최대한 많은 문자를 매칭하려고 시도한다. 이를 탐욕적(greedy)
매칭이라고 하는데 ?
가 붙은 비탐욕적 수량자는 첫 번째 만나는 패턴에서 종료한다. 예를 들어, .? 패턴은 가능한 한 적은 문자를 매칭하려고 시도한다.
[0-9a-zA-Z]{2,3}[-.* ][0-9]{3,4}[-.* ][0-9]{4} -> 숫자 or 알파벳 2개~3개 + - or . or * or 공백 + 0-9숫자 3~4개 + - or . or * or 공백 + 0-9 숫자 4개
[0-9]{2,3}[-.* ][0-9]{3,4}[-.* ][0-9]{4} -> 0-9 숫자 2~3개 + - or . or * or 공백 + 0-9 숫자 3개~4개 + - or . or * or 공백 + 0-9 숫자 4개
[0-9a-zA-Z]+@[0-9a-zA-Z]+.[a-zA-Z]+ -> 0-9 숫자 or 알파벳이 1번 이상 반복(+) + @ + 0-9 숫자 or 알파벳이 1번 이상 반복(+)
^[a-zA-Z0-9+-_.]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$ -> 알파벳 or 0-9숫자 or + or - or _ or .으로 무조건 시작(^)이 1번 이상 반복 + @ + 알파벳 or 0-9숫자 or - 가 1번 이상 반복 + .(역슬래시가 붙으면 그 문자 그대로) + 알파벳 or 0-9숫자 or - or . 이 1번 이상 반복 + 그게 반드시 마지막으로 끝나야 함
.....@----.... -> 아무 문자 5개(\n제외) + @ + - 4개 + 아무문자 4개(\n제외)
\w : 특수 문자 제외한 문자(word)
\w{5} : 5개의 글자(word)
\W : 특수 문자(공백 포함)
\d : 숫자(digit)
\D : not 숫자(digit)
\s : 스페이스(공백)
\S : not 스페이스(공백이 아닌 모든것)
^\d{3}[- .]?\d{3,4}[- .]?\d{4}$ -> 숫자 3개로 반드시 시작함 + - or 공백 or .이 있어도 되고 없어도 됨(0번 or 1번 반복) + 숫자 3개~4개 + - or 공백 or .이 있어도 되고 없어도 됨(0번 or 1번 반복) + 숫자 4개로 반드시 끝나야 함
\[.*] : [로 시작하고 .(모든 문자열이) *(0번 이상 반복) 하며 ]로 끝남
\(.*\) : (로 시작하고 .(모든 문자열이) *(0번 이상 반복) 하며 )로 끝남
\\.*\/ : \로 시작하고 .(모든 문자열이) *(0번 이상 반복) 하며 /로 끝남
-.*- : - 사이에 0개 이상의 문자가 존재
\^\^ : ^^문자를 표기하기 위함
:\) : :) 문자 표시
# 사용되는 패턴
# 1
p = re.compile(r'([0-9]|10)([SDT])([\*\#]?)')
p.findall('1S2D*3T')
# 2
re.findall(r'([0-9]|10)([SDT])([\*\#]?)', '1S2D*3T')
# 자주 사용하는 메서드
# sub() : 매치된 부분을 치환 (str에 replace와 같은 역활) # 가장 많이 사용
# findall() : 매치된 부분 모두 리스트 반환
해당 정규표현식을 만족하는 문자(열)를 리스트로 반환한다.
import re
list(re.findall(r'([0-9]|10)([SDT])([\*\#]?)', '1S2D*3T'))
# [('1', 'S', ''), ('2', 'D', '*'), ('3', 'T', '')]
데이터 안의 정규표현식 부분을 특정 문자로 바꾼다.
import re
def solution(my_string):
return re.sub(r"[aeiou]", "", my_string)
문자열에서 replace와 같은 느낌이다.
import re
text = '''# This is a h1
## This is a h2
### This is a h3
#### This is a h4
##### This is a h5
###### This is a h6
* This is a bulleted list
* This is a nested bulleted list
**This is bold text**
_This is italic text_
~~This text is strikethrough~~
'''
def markdown_to_html(markdown):
html = re.sub(r'### (.*)', r'\1', markdown)
html = re.sub(r'## (.*)', r'\1', html)
html = re.sub(r'# (.*)', r'\1', html)
html = re.sub(r'`(.*)`', r'\1', html)
html = re.sub(r'\*\*(.*)\*\*', r'\1', html)
html = re.sub(r'_(.*)_', r'\1', html)
html = re.sub(r'~~(.*)~~', r'\1', html)
html = re.sub(r'^(>+) (.*)', r'\1\2', html)
# html = re.sub(r'^\* (.*)', r'\1', html, flags=re.M+re.S)
return html
print(markdown_to_html(text))
위의 코드처럼 마크다운 문법의 텍스트를 html로 바꿀 수도 있다.
import re
text = "저의 이메일 주소는 kim123@gmail.com입니다. 친구의 이메일 주소는 lee456@gmail.com입니다."
my_text = re.sub(r'[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}','user@weniv.co.kr', text)
my_text
이것은 예시 문장입니다.
"import re
text = "<p>이것은 <b>예시</b> 문장입니다.</p>"
my_text = re.sub(r'<[^>]+>','', text)
my_text
오늘도 꽤나 많은 내용을 진행했다. 이게 유익하긴 한데 중간중간 비동기 프로그래밍 같은? 부분에서 안드로메다로 가버렸다가 다시 돌아왔다가 했던 것 같다. 오늘 한 것 중에선 정규표현식이 가장 중요해 연습문제도 2개를 내주셨는데 이거를 확실히 내꺼로 만들고 가야겠다고 생각했다. 매번 생각하는 것이지만 강사님이 열정적이시고 파이썬을 엄청 좋아하시는게 느껴진다고 해야되나? 좋은 에너지를 많이 받고 있는 것 같다. 학교 수업이나 다른 강의같은 경우에는 안다뤄주는 심화 부분들 + 실무 경험 등을 알려주시니 너무 좋다. 포기하지 말고 끝까지 해보자.