How We Coding

동영상 강좌 : http://pythonkim.tistory.com/notice/77


# Day_03_05_slicing.py


- 다른 파일의 어떤 내용을 사용하고 싶을 때.


1
import Day_03_05_import
cs


>> Day_02_02_list.py 파일을 불러오기. (.py 는 생략)

>> 위 파일에서 선언한 변수, 함수를 모두 사용할 수 있다. 해당 파일의 내용을 복붙한것과 같은 효과..!!


>> 하지만 우리는 makeRandoms() 의 사용만 원한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import random
 
 
def makeRandoms():
    a = []
    for i in range(10):
        a.append(random.randrange(100))
    return a
 
 
= "unused"
 
 
def a():
    pass
 
 
def b():
    pass
 
 
def c():
    pass
cs



>> 우리가 불러올 파일이 이런식으로 구성되어 있다고 가정하자.

>> makeRandoms() 함수만을 가져다 쓰고 싶다.


>> 하지만 위와 같이 해당 파일을 통채로 import 하면 복붙의 효과이기 때문에

     변수 s, a(), b(), c() 도 가져오게 된다.



- 원하지 않는 내용들을 블럭지정 후 Edit - Indent Selection 을 통해 블럭 내용들을 한번에 탭키 처리 한다.

- 그리고 이것들을 사용하지 않기 위해 아래의 1번 라인을 추가 한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
if __name__ == '__main__':
    s = "unused"
    
    
    def a():
        pass
    
    
    def b():
        pass
    
    
    def c():
        pass
cs


>> 파이썬에는 main() 가 존재하지 않는다. 그래서 이를 흉내낼 필요가 있다. 

>> 위와 같이 여러개의 파일이 같이 사용될 때 특히..!!

>> 그것을 흉내내는 변수가 __name__ 이다.


### __main__ 은 첫번째 실행되는 파일을 의미한다.

### __name__ : 파일별로 존재하는 파일 이름


- 현재 파일에 print(__name__) 을 추가하고, import 한 파일에도 print(__name__) 을 추가한 다음 내용을 확인해보자.


1
2
3
import Day_03_05_import
 
print(__name__)
cs


>> 실행결과


1
2
Day_03_05_import :  Day_03_05_import
__main__
cs


>> 1 : import 한 파일에서 실행된 print(__name__)

>> 2 : 현재 파일에서 실행된 print(__name__), 즉 첫 번째로 실행된 파일이다.



- import 한 파일의 함수 사용하기


1
2
3
Day_03_05_import.random.seed(1)
= Day_03_05_import.makeRandoms()
print(a)    # [17, 72, 97, 8, 32, 15, 63, 97, 57, 60]
cs



- 슬라이싱


1
print(a[0:5])   # [17, 72, 97, 8, 32]
cs


>> [0, 5) 까지의 데이터들을 의미한다. 

>> : 을 이용한 문법을 슬라이싱 이라고 한다.


# 문제

# 뒤쪽 절반 출력하기.


1
print(a[len(a)//2:])
cs


>> print(a[len(a)//2:len(a)]) 도 가능하다.


- 생략

 

1
print(a[:]) # [17, 72, 97, 8, 32, 15, 63, 97, 57, 60]
cs


>> 이런식으로 생략이 가능하다.

>> : 앞의 생략은 맨 앞부터,  : 뒤의 생략은 맨 마지막 까지를 의미한다.



- 슬라이싱을 range() 처럼 사용할 수 있다.


1
2
print(a[::2])   # [17, 97, 32, 63, 57]
print(a[::3])   # [17, 8, 63, 60]
cs


>> 1 : 2칸씩 건너뛴 요소

>> 2 : 3칸씩 건너뛴 요소



- 홀수번째, 짝수번째 요소 출력하기


1
2
3
4
5
# 짝수번째 요소만 출력
print(a[::2])   # [17, 97, 32, 63, 57]
 
# 홀수번째 요소만 출력
print(a[1::2])  # [72, 8, 15, 97, 60]
cs


>> 5 : 1번째 요소부터 2칸씩 건너뛰기..!!



- 거꾸로 출력하기


1
print(a[::-1])  # [60, 57, 97, 63, 15, 32, 8, 97, 72, 17]
cs



1
2
3
4
5
print(a[len(a)-1:0:-1]) # [60, 57, 97, 63, 15, 32, 8, 97, 72]
 
print(a[len(a)-1:-1:-1])    # []
 
print(a[-1:-1:-1])          # []
cs


>> 1 : 마지막 요소만 제외하고 출력이 된다.

>> 3, 5 라인은 같은 코드이다.



- 거꾸로 홀수번째, 짝수번째 요소만 출력하기


1
2
3
4
# 거꾸로 홀수번째 요소만 출력하기
print(a[:]) # [17, 72, 97, 8, 32, 15, 63, 97, 57, 60]
print(a[::-2])      # [60, 97, 15, 8, 72]
print(a[-2::-2])    # [57, 63, 32, 97, 17]
cs




- 얕은복사 review


1
2
3
4
5
6
7
= a
= a
a[0= -1
 
print(a)    # [-1, 72, 97, 8, 32, 15, 63, 97, 57, 60]
print(b)    # [-1, 72, 97, 8, 32, 15, 63, 97, 57, 60]
print(c)    # [-1, 72, 97, 8, 32, 15, 63, 97, 57, 60]
cs


>> a[0] 를 변경했는데, b와 c도 변경됨



- 깊은복사 review


1
2
3
4
5
6
7
8
9
10
11
12
= a
= a
= a.copy()
= a[:]
a[0= -1
 
print(a)    # [-1, 72, 97, 8, 32, 15, 63, 97, 57, 60]
print(b)    # [-1, 72, 97, 8, 32, 15, 63, 97, 57, 60]
print(c)    # [-1, 72, 97, 8, 32, 15, 63, 97, 57, 60]
 
print(d)    # [17, 72, 97, 8, 32, 15, 63, 97, 57, 60]
print(e)    # [17, 72, 97, 8, 32, 15, 63, 97, 57, 60]
cs


>> 3 : 이전에 공부한 깊은복사 방법

>> 4 : 슬라이싱을 이용한 깊은복사 // 슬라이싱은 안쪽에 있는 것을 뽑아내는 과정이기 때문에 항상 복사본을 만든다.



- 짝수번째 요소 출력하기


1
2
3
4
5
6
7
for i in range(0len(a), 2):
    print(a[i], end=' ')        # -1 97 32 63 57 
print()
 
for i in a[::2]:
    print(i, end=' ')           # -1 97 32 63 57 
print()
cs


>> 예전에는 1-3과 같이 하였으나, 이젠 5-7과 같이 하면 된다.




'Language > Python' 카테고리의 다른 글

<3-3> JSON  (0) 2018.03.05
<3-2> Set 과 Dictionary  (0) 2018.03.02
<3-1> 파일 입출력  (0) 2018.02.23
<2-3> 기상청의 전국 날씨정보 파싱, 외부 모듈 추가  (0) 2018.02.22
<2-2> 리스트, 튜플  (0) 2018.02.15

<3-3> JSON

Language/Python2018. 3. 5. 22:34

동영상 강의 : http://pythonkim.tistory.com/notice/77


# Day_03_03_json.py


- 파이선에서는 json 모듈이 있다.


1
import json
cs


http://www.jsontest.com 에 접속해보자


- JSON : JavaScript Object Notation 의 약자.


>> Object 를 문자열로 변환하고, 그 문자열을 다시 Object 로 복원하는 방법.


-


1
j1 = '{"ip": "8.8.8.8"}'

cs

 

>> dictionary 를 포장하고 있는 문자열.

>> 우리는 이것을 dictionary 로 변환할 수 있다. dictionary 가 들어있기 때문..!!


-

1
2
3
4
5
6
7
import json
 
j1 = '{"ip": "8.8.8.8"}'
d1 = json.loads(j1)
print(d1)           # {'ip': '8.8.8.8'}
print(type(d1))     # <class 'dict'>
print(d1['ip'])     # 8.8.8.8
cs



>> 4 : json.loads() 를 통해 json 형태의 문자열을 읽어올 수 있다.

>> json.load() 는 파일로부터 읽어올 때 사용한다.



# 문제

# j2를 해석해서 value 를 출력하기


1
2
3
4
5
6
7
8
9
10
11
12
j2 = '''{
   "Accept-Language": "en-US,en;q=0.8",
   "Host": "headers.jsontest.com",
   "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.3",
   "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
}'''
 
d2 = json.loads(j2)
print(type(d2))     # <class 'dict'>
 
for k, v in d2.items():
    print(k, v)
cs


>> 실행결과

1
2
3
4
Accept-Language en-US,en;q=0.8
Host headers.jsontest.com
Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
cs



- json.dumps()


1
2
3
j3 = json.dumps(d2)
print(type(j3))
print(j3)
cs


>> 실행결과


1
2
<class 'str'>
{"Accept-Language": "en-US,en;q=0.8", "Host": "headers.jsontest.com", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.3", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"}
cs


>> object 를  str 로 변환한다.




- 이전에 만든 kma.csv 파일을 열어보자. (기본적으로 엑셀과 연동이 된다.)

>> 인코딩 문제로 글자가 깨지는 경우


1
= open('Data/kma.cvs''w', encoding='utf-8')
cs


>> 여기에서 인코딩을 지우면 된다고 하는데, 맥에서는 안된다...


...




# Day_03_04_json_kma.py



1
2
3
4
5
6
7
8
9
10
import json
import requests
 
url = 'http://www.kma.go.kr/DFSROOT/POINT/DATA/top.json.txt'
recvd = requests.get(url)
 
print(recvd.text)
 
text = bytes(recvd.text, 'iso-8859-1').decode('utf-8')
print(text)
cs


>> 실행결과


1
2
[{"code":"11","value":"서울특별시"},{"code":"26","value":"부산광역시"},{"code":"27","value":"대구광역시"},{"code":"28","value":"인천광역시"},{"code":"29","value":"광주광역시"},{"code":"30","value":"대전광역시"},{"code":"31","value":"울산광역시"},{"code":"41","value":"경기도"},{"code":"42","value":"강원도"},{"code":"43","value":"충청북도"},{"code":"44","value":"충청남도"},{"code":"45","value":"전라북도"},{"code":"46","value":"전라남도"},{"code":"47","value":"경상북도"},{"code":"48","value":"경상남도"},{"code":"50","value":"제주특별자치도"}]
[{"code":"11","value":"서울특별시"},{"code":"26","value":"부산광역시"},{"code":"27","value":"대구광역시"},{"code":"28","value":"인천광역시"},{"code":"29","value":"광주광역시"},{"code":"30","value":"대전광역시"},{"code":"31","value":"울산광역시"},{"code":"41","value":"경기도"},{"code":"42","value":"강원도"},{"code":"43","value":"충청북도"},{"code":"44","value":"충청남도"},{"code":"45","value":"전라북도"},{"code":"46","value":"전라남도"},{"code":"47","value":"경상북도"},{"code":"48","value":"경상남도"},{"code":"50","value":"제주특별자치도"}]
cs


>> text 데이터는 딕셔너리 리스트의 형태이다..!!


>> 인코딩이 깨지는 것에 대한 해결책은 9번 라인으로 해결.

>> 4 라인의 url 을 브라우저에서 직접 실행시 json 형식의 내용을 그대로 확인할 수 있다. (맥에서는 여전히 깨져서 나온다..ㅜ)



< JSON 에서의 기본 규칙 >

- 맨 처음 나오는 것은 최상위 객체로 배열(파이썬에서는 리스트) 아니면 사전의 형태.

- int 값을 json 으로 전달할 수 없다.



# 문제

# 코드와 도시 이름만 출력해 보기.


1
2
3
4
5
6
items = json.loads(text)
print(items)
print(type(items))   # <class 'list'>
 
for item in items:
    print(item['code'], item['value'])
cs


>> 실행결과


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[{'code': '11', 'value': '서울특별시'}, {'code': '26', 'value': '부산광역시'}, {'code': '27', 'value': '대구광역시'}, {'code': '28', 'value': '인천광역시'}, {'code': '29', 'value': '광주광역시'}, {'code': '30', 'value': '대전광역시'}, {'code': '31', 'value': '울산광역시'}, {'code': '41', 'value': '경기도'}, {'code': '42', 'value': '강원도'}, {'code': '43', 'value': '충청북도'}, {'code': '44', 'value': '충청남도'}, {'code': '45', 'value': '전라북도'}, {'code': '46', 'value': '전라남도'}, {'code': '47', 'value': '경상북도'}, {'code': '48', 'value': '경상남도'}, {'code': '50', 'value': '제주특별자치도'}]
<class 'list'>
11 서울특별시
26 부산광역시
27 대구광역시
28 인천광역시
29 광주광역시
30 대전광역시
31 울산광역시
41 경기도
42 강원도
43 충청북도
44 충청남도
45 전라북도
46 전라남도
47 경상북도
48 경상남도
50 제주특별자치도
cs

 




'Language > Python' 카테고리의 다른 글

<3-4> __name__, 리스트 슬라이싱  (0) 2018.03.08
<3-2> Set 과 Dictionary  (0) 2018.03.02
<3-1> 파일 입출력  (0) 2018.02.23
<2-3> 기상청의 전국 날씨정보 파싱, 외부 모듈 추가  (0) 2018.02.22
<2-2> 리스트, 튜플  (0) 2018.02.15

동영상 강의 : http://pythonkim.tistory.com/notice/77



# Day_03_02_dict.py


- set 과 dictionary


1
2
3
4
5
= {}
print(type(a), a)  # <class 'dict'> {}
 
= {1}
print(type(b), b)   # <class 'set'> {1}
cs


>> 중괄호를 이용한 컬렉션은 두가지 : set 과 dictionary

>> dictionary 가 set 보다 백만배 중요하다고 한다.



- dictionary 의 초기화


1
2
= {1:2}
print(type(c), c)   # <class 'dict'> {1: 2}
cs




- Set


1
2
3
4
5
= {123123123}
print(type(d), d)   # <class 'set'> {1, 2, 3}
 
= [123123123]
print(type(e), e)   # <class 'list'> [1, 2, 3, 1, 2, 3, 1, 2, 3]
cs


>> set은 중복된 데이터를 허용하지 않는다.

>> 반면, list 는 중복된 데이터를 허용한다.



# 문제

# 리스트에 들어있는 중복된 데이터를 제거하기


1
2
3
4
5
= [123123123]
print(type(e), e)   # <class 'list'> [1, 2, 3, 1, 2, 3, 1, 2, 3]
 
= list(set(e))
print(e)            # [1, 2, 3]
cs


>> set(e) 의 결과는 set 이므로 list 로 캐스팅.



- Dictionary


- 초기화


1
2
= {'color''red''price'100}
print(d)            # {'color': 'red', 'price': 100}
cs


>> key: value 의 쌍으로 구성된다.



- 초기화 2


1
2
3
4
= dict(color='red', price=100)
print(d)            # {'color': 'red', 'price': 100}
print(d['color'])   # red
print(d['price'])   # 100
cs


>> 위와 아래의 차이점은 거의 없다고 보면 된다.

>> 아래의 방법으로 초기화 하는 것을 선호한다고 한다. dict() 함수를 이용해서 dictionary 만드는 방법

>> key 값에 ' ' 를 생략하면 자동으로 포함이 된다.

>> 리스트는 요소들의 순서가 보장되지만, 딕셔너리는 순서를 보장하지 않는다.


>> 3, 4 : dictionary 요소 접근



 - dictionary 에서 데이터 삽입


1
2
3
4
5
6
# 데이터 삽입
d['title'= 'pen'
print(d)        # {'color': 'red', 'price': 100, 'title': 'pen'}
 
d['title'= 'bread'
print(d)        # {'color': 'red', 'price': 100, 'title': 'bread'}
cs


>> 2 : insert

>> 4 : update (title 이란 키값이 이미 존재하므로..!!)

>> dictionary 는 키값의 중복을 허용하지 않는다..!!



-

1
2
3
print(d.keys())     # dict_keys(['color', 'price', 'title'])
print(d.values())   # dict_values(['red', 100, 'bread'])
print(d.items())    # dict_items([('color', 'red'), ('price', 100), ('title', 'bread')])
cs



# 문제

# keys, values, items 를 for문과 연결해서 처리해보자.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
for k in d.keys():
   print(k, d[k])
print('-'*10)
 
for v in d.values():
    print(v)
print('-'*10)
 
for i in d.items():
    print(i, i[0], i[1])
print('-'*10)
 
for k, v in d.items():
    print(k, v)
cs


>> 2 : 키값을 통해 value 를 알 수 있다.

>> 5 : value 만으로는 아무것도 할 수 없다.

>> 9 : i 의 결과는 튜플이다. 그렇기 때문데, 13-14와 같은 형태로 이용을 한다.


>> 실행결과

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
color red
price 100
title bread
----------
red
100
bread
----------
('color', 'red') color red
('price', 100) price 100
('title', 'bread') title bread
----------
color red
price 100
title bread
cs

  


- enumerate()


1
2
for i in enumerate(d.items()):
    print(i)
cs


>> 인덱스를 포함시킨 튜플의 형태가 된다.


>> 실행결과

1
2
3
(0, ('color', 'red'))
(1, ('price', 100))
(2, ('title', 'bread'))
cs



- 튜플의 괄호 없애기


1
2
for i in enumerate(d.items()):
    print(i[0], i[1][0], i[1][1])
cs


>> 실행결과

1
2
3
0 color red
1 price 100
2 title bread
cs



-

1
2
3
4
5
# for i, k, v in enumerate(d.items()):
#     print(i, k, v)
 
for i, (k, v) in enumerate(d.items()):
    print(i, k, v)
cs


>> 1 은 에러 : 하나의 인덱스와 하나의 튜플을 던져주므로 4와 같이 받아야 한다. (튜플의 요소는 2개인 상태)



- 딕셔너리를 통채로 전달해서 키값을 출력하는 방법


1
2
for k in d:
    print(k)
cs


>> 실행결과


1
2
3
color
price
title
cs


>> 이러한 이유로 d.keys() 를 사용하지 않는다.

'Language > Python' 카테고리의 다른 글

<3-4> __name__, 리스트 슬라이싱  (0) 2018.03.08
<3-3> JSON  (0) 2018.03.05
<3-1> 파일 입출력  (0) 2018.02.23
<2-3> 기상청의 전국 날씨정보 파싱, 외부 모듈 추가  (0) 2018.02.22
<2-2> 리스트, 튜플  (0) 2018.02.15

동영상 강의 : http://pythonkim.tistory.com/notice/77


# Day_03_01_file.py


- 파일에는 두가지 종류의 파일이 있다. 우리가 읽을 수 있는 파일(텍스트 파일)과 읽을 수 없는 파일(바이너리 피알)..!!


- 우선 Data 폴더를 만들고 텍스트 파일 하나를 만들자.


김인육, 사랑의 물리학


질량의 크기는 부피와 비례하지 않는다


제비꽃같이 조그마한 그 계집애가

꽃잎같이 하늘거리는 그 계집애가

지구보다 더 큰 질량으로 나를 끌어당긴다.

순간, 나는

뉴턴의 사과처럼

사정없이 그녀에게로 굴러 떨어졌다

쿵 소리를 내며, 쿵쿵 소리를 내며


심장이

하늘에서 땅까지 아찔한 진자운동을 계속하였다

첫사랑이었다.


>> 위의 시를 poem.txt 파일에 복붙하쟈.



- open() , close()


1
2
3
4
5
6
7
8
def read_1(filename):
    f = open(filename, 'r')
 
    f.close()
 
 
filename = 'Data/poem.txt'
read_1(filename)
cs


>> 7 : 경로설정을 잘 해줘야한다. 현재 디렉토리에 있는 Data 폴더에 있는 poem.txt 라는 파일.

>> 프로젝트 폴더가 현재 디렉토리라고 여겨진다.


>> 2 : open() 에서의 옵션 'r' >> 파일을 읽겠다는 뜻.

>> 4 : open() 을 하고 볼일을 다 봤으면 항상 close() 를 해줘야한다.


- 경로에는 절대경로와 상대결로가 있다.

>> 절대경로 : 경로의 풀네임

>> 상대경로 : 현재 경로 기준으로 판단. // . 은 현재 디렉토리, // .. 은 상위 디렉토리

>> 일반적으로 상대경로를 많이 사용한다고 한다.


- 경로를 잘 설정했는데도 에러가 발생했다면 인코딩 문제를 의심해볼 수 있다.


1
= open(filename, 'r', encoding='utf-8')
cs


>> 세번째 옵션으로 인코딩 옵션을 설정한다.

>> 현재 전 세계적으로 텍스트파일에 대한 표준은 utf-8 이라고 한다.

>> html 에서 기본적으로 이것을 사용한다고 한다.



- readlines()


1
2
3
4
5
6
7
8
9
10
11
def read_1(filename):
    f = open(filename, 'r', encoding='utf-8')
 
    lines = f.readlines()
    print(lines)
 
    f.close()
 
 
filename = 'Data/poem.txt'
read_1(filename)
cs


>> 4, 5 라인 추가. // readline 과 혼동하지 말자.

>> 실행결과

['김인육, 사랑의 물리학\n', '\n', '질량의 크기는 부피와 비례하지 않는다\n', '\n', '제비꽃같이 조그마한 그 계집애가\n', '꽃잎같이 하늘거리는 그 계집애가\n', '지구보다 더 큰 질량으로 나를 끌어당긴다.\n', '순간, 나는\n', '뉴턴의 사과처럼\n', '사정없이 그녀에게로 굴러 떨어졌다\n', '쿵 소리를 내며, 쿵쿵 소리를 내며\n', '\n', '심장이\n', '하늘에서 땅까지 아찔한 진자운동을 계속하였다\n', '첫사랑이었다.']



- 따로따로 출력을 해보자

1
2
3
4
5
6
7
8
9
10
11
12
13
def read_1(filename):
    f = open(filename, 'r', encoding='utf-8')
 
    lines = f.readlines()
 
    for line in lines:
        print(line)
 
    f.close()
 
 
filename = 'Data/poem.txt'
read_1(filename)
cs

>> 6, 7 라인의 변경

>> 실행결과


김인육, 사랑의 물리학




질량의 크기는 부피와 비례하지 않는다




제비꽃같이 조그마한 그 계집애가


꽃잎같이 하늘거리는 그 계집애가


지구보다 더 큰 질량으로 나를 끌어당긴다.


순간, 나는


뉴턴의 사과처럼


사정없이 그녀에게로 굴러 떨어졌다


쿵 소리를 내며, 쿵쿵 소리를 내며




심장이


하늘에서 땅까지 아찔한 진자운동을 계속하였다


첫사랑이었다. 


>> 줄바꿈이 심하다. 기본적으로 문자열 내부에 개행을 포함하며, print() 또한 개행을 포함하기 때문이다.



- 7 라인의 print() 에서 end='' 옵션을 추가해보쟈


1
2
3
4
5
6
7
8
9
10
11
12
13
def read_1(filename):
    f = open(filename, 'r', encoding='utf-8')
 
    lines = f.readlines()
 
    for line in lines:
        print(line, end='')
 
    f.close()
 
 
filename = 'Data/poem.txt'
read_1(filename)
cs


>> 실행결과

김인육, 사랑의 물리학


질량의 크기는 부피와 비례하지 않는다


제비꽃같이 조그마한 그 계집애가

꽃잎같이 하늘거리는 그 계집애가

지구보다 더 큰 질량으로 나를 끌어당긴다.

순간, 나는

뉴턴의 사과처럼

사정없이 그녀에게로 굴러 떨어졌다

쿵 소리를 내며, 쿵쿵 소리를 내며


심장이

하늘에서 땅까지 아찔한 진자운동을 계속하였다

첫사랑이었다. 


>> 하지만 파일을 읽어온 목적이 화면에 출력하는 것은 아니므로, 위와 같은 행위는 바람직하지 않다고 하신다.

>> 출력은 눈으로 확인용일 뿐, 중요하진 않다.



- strip() 사용하기


>> 개행문자가 필요한지 아닌지는 상황에 따라 다를 것이다.

>> 여기서는 필요 없어보인다. 그래서 strip() 을 사용

>> strip() : 문자열 양 끝에 있는 공백을 제거


1
2
3
4
5
6
7
8
9
10
11
12
13
def read_1(filename):
    f = open(filename, 'r', encoding='utf-8')
 
    lines = f.readlines()
 
    for line in lines:
        print(line.strip())
 
    f.close()
 
 
filename = 'Data/poem.txt'
read_1(filename)
cs


>> 7 라인과 같이 사용한다.



- strip() 사용법


1
2
3
4
5
temp = '\t\t\n\n   apple koong   \n\n\t\t'
print('[{}]'.format(temp))
 
temp = temp.strip()
print('[{}]'.format(temp))
cs


>> 2 의 실행결과

[


   apple koong   


]


>> 5 의 실행결과

[apple koong]


>> 문자열 양 끝의 모든 공백들이 제거되었다.




- 파일읽기 2


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def read_2(filename):
    f = open(filename, 'r', encoding='utf-8')
 
    while True:
        line = f.readline()
        # if len(line) == 0: break; # EOF
        if not line: break;
        print(line.strip())
 
 
    f.close()
 
 
filename = 'Data/poem.txt'
read_2(filename)
cs


>> 5 : readline() 함수는 한줄씩 읽어온다.

>> 6 : EOF 를 만나면 line 의 길이는 0이 된다. 하지만 7 라인과 같은 코딩을 선호한다고 한다.

>> 7 : Python 에서는 비어있는 것에 대해 false 로 판단한다.



- 파일읽기 3


1
2
3
4
5
6
7
8
9
10
11
def read_3(filename):
    f = open(filename, 'r', encoding='utf-8')
 
    for line in f:
        print(line.strip())
 
    f.close()
 
 
filename = 'Data/poem.txt'
read_3(filename)
cs


>> 4 : for in 문에서 in 다음에는 이터러블한 것이라면 올 수 있다. 이처럼 파일도 올 수 있다.

>> EOF 를 만나면 알아서 끝난다.

>> 가장 심플한 코드.



- 파일읽기 4 : with 구문 사용


1
2
3
4
5
6
7
8
9
10
11
def read_4(filename):
    with open(filename, 'r', encoding='utf-8') as f:
 
        for line in f:
            print(line.strip())
 
        # f.close()
 
 
filename = 'Data/poem.txt'
read_4(filename)
cs


>> 2 : with 구문 사용, as f: f 라는 별칭까지 준다.

>> 7 : close() 가 필요가 없다. with 구문의 장점(자동으로 호출이 된다.)



- 파일읽기 5

- 일반적으로 파일을 다루는 코드 (리스트에 넣어서 처리)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 일반적으로 파일을 다루는 코드.
# 리스트에 넣어서 처리
def read_5(filename):
    lines = []
    with open(filename, 'r', encoding='utf-8') as f:
        for line in f:
            # print(line.strip())
            lines.append(line.strip())
 
    return lines
 
 
filename = 'Data/poem.txt'
lines = read_5(filename)
cs


>>



- readlines() 가 존재하는 이유.


1
2
3
4
5
6
7
8
9
10
11
12
def read_readlines(filename):
    f = open(filename, 'r', encoding='utf-8')
 
    lines = f.readlines()
 
    f.close()
    return ''.join(lines)
 
 
filename = 'Data/poem.txt'
text_all = read_readlines(filename)
print(text_all)
cs


>> join() 을 호출하기 위해 존재한다고 한다.

>> read_readlines() 가 리턴한 데이터의 타입은 문자열..!!

>> join() 의 역할은 리스트 안에 들어있는 문자열들을 한번에 결합

>> 하나의 변수로 파일의 내용을 다루고자 할 때 readlines() 를 사용한다.


>> 실행결과

김인육, 사랑의 물리학


질량의 크기는 부피와 비례하지 않는다


제비꽃같이 조그마한 그 계집애가

꽃잎같이 하늘거리는 그 계집애가

지구보다 더 큰 질량으로 나를 끌어당긴다.

순간, 나는

뉴턴의 사과처럼

사정없이 그녀에게로 굴러 떨어졌다

쿵 소리를 내며, 쿵쿵 소리를 내며


심장이

하늘에서 땅까지 아찔한 진자운동을 계속하였다

첫사랑이었다. 



cf) 


1
return '***'.join(lines)
cs


>> 실행결과


김인육, 사랑의 물리학

***

***질량의 크기는 부피와 비례하지 않는다

***

***제비꽃같이 조그마한 그 계집애가

***꽃잎같이 하늘거리는 그 계집애가

***지구보다 더 큰 질량으로 나를 끌어당긴다.

***순간, 나는

***뉴턴의 사과처럼

***사정없이 그녀에게로 굴러 떨어졌다

***쿵 소리를 내며, 쿵쿵 소리를 내며

***

***심장이

***하늘에서 땅까지 아찔한 진자운동을 계속하였다

***첫사랑이었다. 




- split() 과 join()


1
2
3
4
5
6
= 'AA,BB,CC'
= a.split(',')
print(b)            # ['AA', 'BB', 'CC']
 
= ''.join(b)
print(c)            # AABBCC
cs


>> 3, 6 의 실행결과는 주석으로 확인.

>> spit() 의 결과는 리스트



- 파일 쓰기


1
2
3
4
5
6
7
8
def write():
    f = open('Data/write.txt''w', encoding='utf-8')
    f.write('Hello ')
    f.write('Python')
    f.close()
 
 
write()
cs



>> Data 폴더에 write.txt 파일이 생성되고, 'Hello Python' 문자열이 저장되어 있다.



- command 키 누른 상태로 마우스를 open() 위에 가져다 놓기 (win 에서는 ctrl)

>> open() 에 대한 설명을 볼 수 있다.



- 기상청 날씨정보를 파싱 후 파일에 저장


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import requests
import re
 
url = 'http://www.weather.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=108'
recvd = requests.get(url)
 
locations = re.findall(r'<location wl_ver="3">.+?</location>', recvd.text, re.DOTALL)
 
= open('Data/kma.csv''w', encoding='utf-8')
 
def findData():
    for loc in locations:
        prov = re.findall(r'<province>(.+)</province>', loc)
        city = re.findall(r'<city>(.+)</city>', loc)
        data = re.findall(r'<data>(.+)</data>', loc, re.DOTALL)
 
        for datum in data:
            mode = re.findall(r'<mode>(.+?)</mode>', datum)
            tmEf = re.findall(r'<tmEf>(.+?)</tmEf>', datum)
            wf   = re.findall(r'<wf>(.+?)</wf>', datum)
            tmn  = re.findall(r'<tmn>(.+?)</tmn>', datum)
            tmx  = re.findall(r'<tmx>(.+?)</tmx>', datum)
            reli = re.findall(r'<reliability>(.+?)</reliability>', datum)
 
            row = '{},{},{},{},{},{},{},{}'.format(prov[0], city[0], mode[0], tmEf[0], wf[0], tmn[0], tmx[0], reli[0])
            print(row)
            f.write(row)
            f.write('\n')   # 개행문자는 자동으로 처리되지 않으므로.
 
 
findData()
f.close()
cs


'Language > Python' 카테고리의 다른 글

<3-3> JSON  (0) 2018.03.05
<3-2> Set 과 Dictionary  (0) 2018.03.02
<2-3> 기상청의 전국 날씨정보 파싱, 외부 모듈 추가  (0) 2018.02.22
<2-2> 리스트, 튜플  (0) 2018.02.15
<2-1> 제어문과 반복문의 연결고리  (0) 2018.02.06

동영상 강의 : http://pythonkim.tistory.com/notice/77


Day_02_03_kma.py


- import requests 에서 requests 는 외부 모듈.


- PyCharm 에서 외부 모듈 추가하기.


>>  preferences (Mac) - Project - Project Interpreter - "+ 버튼" 클릭 - "requests" 검색 - Install Package 


1
2
3
4
5
6
import requests
import re
 
url = 'http://www.naver.com'
recvd = requests.get(url)
print(recvd)    # <Response [200]>
cs



>> www.naver.com 으로부터 데이터를 성공적으로 가져온 상태. (200)



1
print(recvd.text)
cs


>> Chrome 에서 페이지 소스보기 통해 확인할 수 있는 html 소스가 출력된다.



### 기상청의 전국 날씨정보 파싱


http://www.kma.go.kr/index.jsp 에서 날씨누리 바로가기 - 생활과 산업 - 서비스 - RSS 로 이동




 RSS란?


 RSS(Really Simple Syndication, Rich Site Summary)란 블로그처럼 컨텐츠 업데이트가   

 자주 일어나는 웹사이트에서, 업데이트된 정보를 쉽게 구독자들에게 제공하기 위해 XML을 

 기초로 만들어진 데이터 형식입니다. RSS서비스를 이용하면 업데이트된 정보를 찾기 위해 

 홈페이지에 일일이 방문하지 않아도 업데이트 될 때마다 빠르고 편리하게 확인할 수 

 있습니다. 





- 전국의 중기예보 RSS 클릭 후 URL 클립보드에 복사.


1
2
3
4
url = 'http://www.weather.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=108'
recvd = requests.get(url)
print(recvd)    # <Response [200]>
print(recvd.text)
cs


>> 크롤링 이라고 한다. (python 이 편리한 이유)



-


This XML file does not appear to have any style information associated with it. The document tree is shown below.


>> html 은 style 정보가 포함되어 있다.

>> xml 은 순수하게 데이터만 들어가있다.

>> 데이터 전송 포맷의 두가지 (xml, json)


http://www.weather.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=108 에서 날씨 데이터 찾아보기.


>> <item> - <description> - <body> 안에서 확인가능


>> xml 이든 html 이든 여는태그가 있으면 닫는태그가 있다...!!


1
2
3
4
5
6
url = 'http://www.weather.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=108'
recvd = requests.get(url)
 
tmp = re.findall(r'<province>서울ㆍ인천ㆍ경기도</province>', recvd.text)
print(tmp)  # ['<province>서울ㆍ인천ㆍ경기도</province>', '<province>서울ㆍ인천ㆍ경기도</province>', '<province>서울ㆍ인천ㆍ경기도</province>', '<province>서울ㆍ인천ㆍ경기도</province>']
print(len(tmp)) # 4
cs



- 모든 <province> 태그 가져오기 (정규표현식 이용)


1
2
3
prov = re.findall(r'<province>.+</province>', recvd.text)
print(prov) # ['<province>서울ㆍ인천ㆍ경기도</province>', '<province>서울ㆍ인천ㆍ경기도</province>', '<province>서울ㆍ인천ㆍ경기도</province>', '<province>서울ㆍ인천ㆍ경기도</province>', '<province>강원도영서</province>', '<province>강원도영서</province>', '<province>강원도영동</province>', '<province>대전ㆍ세종ㆍ충청남도</province>', '<province>대전ㆍ세종ㆍ충청남도</province>', '<province>대전ㆍ세종ㆍ충청남도</province>', '<province>충청북도</province>', '<province>광주ㆍ전라남도</province>', '<province>광주ㆍ전라남도</province>', '<province>광주ㆍ전라남도</province>', '<province>전라북도</province>', '<province>전라북도</province>', '<province>부산ㆍ울산ㆍ경상남도</province>', '<province>부산ㆍ울산ㆍ경상남도</province>', '<province>부산ㆍ울산ㆍ경상남도</province>', '<province>대구ㆍ경상북도</province>', '<province>대구ㆍ경상북도</province>', '<province>대구ㆍ경상북도</province>', '<province>제주도</province>', '<province>제주도</province>']
print(len(prov))    # 24
cs



>> <province>.+</province> 패턴은 

     <province> 로 시작하고 하나 이상의 문자가 있고, </province> 로 끝나는 패턴



# 문제

# 전체 location 가져오기


- 상위 데이터를 가져온 다음, 하위 데이터를 분리하는 방식으로 진행해야 한다.!!

- 태그를 타이핑 하지 말고 긁어오쟈 (블럭지정 후 복붙)


1
2
location = re.findall(r'<location wl_ver="3">.+</location>', recvd.text)
print(len(location))
cs


>> 실행 결과는 0 이다.

>> 위의 예제의 경우 여는 태그와 닫는 태그 사이에 한줄에 하나의 데이터만 있지만, 이 예제의 경우 데이터가 여러줄에 걸쳐서 존재한다.

>> 옵션을 추가해서 해결할 수 있다.


1
2
location = re.findall(r'<location wl_ver="3">.+</location>', recvd.text, re.DOTALL)
print(len(location))
cs


>> re.DOTALL 옵션 추가. 내가 찾고자 하는 패턴이 여러줄에 걸쳐있을 때 사용. 

>> 정확히는 개행 문자를 무시해준다.

>> 하지만 실행결과는 1.

>> 가장 짧은 패턴과, 가장 긴 패턴 중 가장 긴 패턴을 디폴트로 찾는다. (Greedy 방식)



>> 데이터가 위와 같이 있는 경우, 첫번째 한줄이 가장 짧은 패턴, 모든 줄을 포함 시킨 것이 가장 긴 패턴이 된다.



- non-greedy 방식으로 하려면 '?' 하나를 추가하면 된다.


1
2
locations = re.findall(r'<location wl_ver="3">.+?</location>', recvd.text, re.DOTALL)
print(len(locations))
cs


>> .+? 라고 적음. ? 는 작은 녀석을 먼저 찾았을 때 멈추게 한다.

>> 실행결과는 24


- 이젠 24개의 데이터에서 원하는 데이터를 다시 또 찾으면 된다.


1
2
3
def printLoc():
    for loc in locations:
        print(loc)
cs


>> 24개의 location 확인 가능



# 문제

# province 를 찾아서 출력 


1
2
3
4
def printProvince():
    for loc in locations:
        prov = re.findall(r'<province>.+</province>', loc)
        print(prov)
cs


>> 24 개의 <province> 데이터를 출력한다.

>> 한줄안에 있으므로 re.DOTALL 없어도 된다.


>> 실행결과


['<province>서울ㆍ인천ㆍ경기도</province>']

['<province>서울ㆍ인천ㆍ경기도</province>']

['<province>서울ㆍ인천ㆍ경기도</province>']

['<province>서울ㆍ인천ㆍ경기도</province>']

['<province>강원도영서</province>']

['<province>강원도영서</province>']

['<province>강원도영동</province>']

['<province>대전ㆍ세종ㆍ충청남도</province>']

['<province>대전ㆍ세종ㆍ충청남도</province>']

['<province>대전ㆍ세종ㆍ충청남도</province>']

['<province>충청북도</province>']

['<province>광주ㆍ전라남도</province>']

['<province>광주ㆍ전라남도</province>']

['<province>광주ㆍ전라남도</province>']

['<province>전라북도</province>']

['<province>전라북도</province>']

['<province>부산ㆍ울산ㆍ경상남도</province>']

['<province>부산ㆍ울산ㆍ경상남도</province>']

['<province>부산ㆍ울산ㆍ경상남도</province>']

['<province>대구ㆍ경상북도</province>']

['<province>대구ㆍ경상북도</province>']

['<province>대구ㆍ경상북도</province>']

['<province>제주도</province>']

['<province>제주도</province>']



>> 여기서 우리가 필요한 것은 <province> 태그 안의 데이터이므로 , 태그 이름까지는 없어도 된다..!!


1
2
3
4
def printProvinceData():
    for loc in locations:
        prov = re.findall(r'<province>(.+)</province>', loc)
        print(prov)
cs


>> 괄호를 치면 된다.!!

>> 실행결과 


['서울ㆍ인천ㆍ경기도']

['서울ㆍ인천ㆍ경기도']

['서울ㆍ인천ㆍ경기도']

['서울ㆍ인천ㆍ경기도']

['강원도영서']

['강원도영서']

['강원도영동']

['대전ㆍ세종ㆍ충청남도']

['대전ㆍ세종ㆍ충청남도']

['대전ㆍ세종ㆍ충청남도']

['충청북도']

['광주ㆍ전라남도']

['광주ㆍ전라남도']

['광주ㆍ전라남도']

['전라북도']

['전라북도']

['부산ㆍ울산ㆍ경상남도']

['부산ㆍ울산ㆍ경상남도']

['부산ㆍ울산ㆍ경상남도']

['대구ㆍ경상북도']

['대구ㆍ경상북도']

['대구ㆍ경상북도']

['제주도']

['제주도']




# Data 찾기


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# Data 찾기
 
def findData():
    for loc in locations:
        prov = re.findall(r'<province>(.+)</province>', loc)
        city = re.findall(r'<city>(.+)</city>', loc)
        data = re.findall(r'<data>(.+)</data>', loc, re.DOTALL)
 
        #print(prov[0], prov)
        #print(city[0])
        # print(data)
        # print(len(data))    # 1
 
        for datum in data:
            # print(datum)
 
            # 문제
            # mode 를 비롯한 나머지를 찾아보기
            mode = re.findall(r'<mode>(.+?)</mode>', datum)
            tmEf = re.findall(r'<tmEf>(.+?)</tmEf>', datum)
            wf   = re.findall(r'<wf>(.+?)</wf>', datum)
            tmn  = re.findall(r'<tmn>(.+?)</tmn>', datum)
            tmx  = re.findall(r'<tmx>(.+?)</tmx>', datum)
            reli = re.findall(r'<reliability>(.+?)</reliability>', datum)
            # print(prov[0], city[0], mode[0], tmEf[0], wf[0], tmn[0], tmx[0], reli[0])
 
            row = '{}, {}, {}, {}, {}, {}, {}, {}'.format(prov[0], city[0], mode[0], tmEf[0], wf[0], tmn[0], tmx[0], reli[0])
            print(row)
 
 
findData()
 
 
 
cs


>> datum 하나의 출력 결과


<data>

<mode>A01</mode>

<tmEf>2018-03-02 00:00</tmEf>

<wf>구름많음</wf>

<tmn>6</tmn>

<tmx>13</tmx>

<reliability>보통</reliability>

</data>



>> 25 : print(prov[0], city[0], mode[0], tmEf[0], wf[0], tmn[0], tmx[0], reli[0]) 의 결과


서울ㆍ인천ㆍ경기도 서울 A02 2018-02-24 00:00 구름조금 -2 7 높음

서울ㆍ인천ㆍ경기도 인천 A02 2018-02-24 00:00 구름조금 -2 5 높음

서울ㆍ인천ㆍ경기도 수원 A02 2018-02-24 00:00 구름조금 -3 7 높음

서울ㆍ인천ㆍ경기도 파주 A02 2018-02-24 00:00 구름조금 -7 6 높음

강원도영서 춘천 A02 2018-02-24 00:00 구름조금 -5 6 보통

강원도영서 원주 A02 2018-02-24 00:00 구름조금 -4 6 보통

강원도영동 강릉 A02 2018-02-24 00:00 구름조금 -1 7 보통

대전ㆍ세종ㆍ충청남도 대전 A02 2018-02-24 00:00 구름조금 -4 8 보통

대전ㆍ세종ㆍ충청남도 세종 A02 2018-02-24 00:00 구름조금 -5 7 보통

대전ㆍ세종ㆍ충청남도 홍성 A02 2018-02-24 00:00 구름조금 -4 7 보통

충청북도 청주 A02 2018-02-24 00:00 구름조금 -3 8 보통

광주ㆍ전라남도 광주 A02 2018-02-24 00:00 구름조금 0 12 보통

광주ㆍ전라남도 목포 A02 2018-02-24 00:00 구름조금 1 10 보통

광주ㆍ전라남도 여수 A02 2018-02-24 00:00 구름조금 3 12 보통

전라북도 전주 A02 2018-02-24 00:00 구름조금 -2 9 보통

전라북도 군산 A02 2018-02-24 00:00 구름조금 -3 7 보통

부산ㆍ울산ㆍ경상남도 부산 A02 2018-02-24 00:00 구름조금 3 12 보통

부산ㆍ울산ㆍ경상남도 울산 A02 2018-02-24 00:00 구름조금 0 11 보통

부산ㆍ울산ㆍ경상남도 창원 A02 2018-02-24 00:00 구름조금 1 12 보통

대구ㆍ경상북도 대구 A02 2018-02-24 00:00 구름조금 -1 12 보통

대구ㆍ경상북도 안동 A02 2018-02-24 00:00 구름조금 -3 10 보통

대구ㆍ경상북도 포항 A02 2018-02-24 00:00 구름조금 1 11 보통

제주도 제주 A02 2018-02-24 00:00 구름조금 5 12 보통

제주도 서귀포 A02 2018-02-24 00:00 구름조금 7 13 보통



>> 27 : 데이터를 재사용하기 위해 row 및 문자열 포맷 사용.

>> 데이터와 데이터 사이에 콤마로 구분. comma separated // CSV 



- 이런식으로도 할 수 있다.


1
2
items = re.findall(r'<mode>(.+?)</mode>.+<tmEf>(.+?)</tmEf>.+<wf>(.+?)</wf>', datum, re.DOTALL)
print(items)
cs


>> 태그와 태그 사이에 .+ 추가. re.DOTALL 옵션 추가.

>> 실행결과 (리스트 안의 튜플로 된 구조이다.)


[('A02', '2018-03-03 00:00', '구름조금')]

[('A02', '2018-03-03 00:00', '구름조금')]

[('A02', '2018-03-03 00:00', '구름조금')]

[('A02', '2018-03-03 00:00', '구름조금')]

[('A02', '2018-03-03 00:00', '구름조금')]

[('A02', '2018-03-03 00:00', '구름조금')]

[('A02', '2018-03-03 00:00', '구름조금')]

[('A02', '2018-03-03 00:00', '구름조금')]

[('A02', '2018-03-03 00:00', '구름조금')]

[('A02', '2018-03-03 00:00', '구름조금')]

[('A02', '2018-03-03 00:00', '구름조금')]

[('A02', '2018-03-03 00:00', '구름조금')]

[('A02', '2018-03-03 00:00', '구름조금')]

[('A02', '2018-03-03 00:00', '구름조금')]

[('A02', '2018-03-03 00:00', '구름조금')]

[('A02', '2018-03-03 00:00', '구름조금')]

[('A02', '2018-03-03 00:00', '구름조금')]

[('A02', '2018-03-03 00:00', '구름조금')]

[('A02', '2018-03-03 00:00', '구름조금')]

[('A02', '2018-03-03 00:00', '구름조금')]

[('A02', '2018-03-03 00:00', '구름조금')]

[('A02', '2018-03-03 00:00', '구름조금')]

[('A02', '2018-03-03 00:00', '구름많음')]

[('A02', '2018-03-03 00:00', '구름많음')]


-  

1
2
= items[0]
print(t[0], t[1], t[2])
cs


>> item 은 리스트

>> items[0] 은 튜플





1
2
3
4
5
6
7
8
def findLoc():
    for loc in locations:
        items = re.findall(r'<mode>(.+?)</mode>.+?<tmEf>(.+?)</tmEf>.+?<wf>(.+?)</wf>', loc, re.DOTALL)
        print(items)
        print(len(items))
 
 
findLoc()
cs


>> 태그와 태그 사이 .+ 가 아닌 .+? 이다!!

>> 실행결과의 일부


[('A02', '2018-02-24 00:00', '구름조금'), ('A02', '2018-02-24 12:00', '구름많음'), ('A02', '2018-02-25 00:00', '구름많음'), ('A02', '2018-02-25 12:00', '구름많음'), ('A02', '2018-02-26 00:00', '구름조금'), ('A02', '2018-02-26 12:00', '구름조금'), ('A02', '2018-02-27 00:00', '구름많음'), ('A02', '2018-02-27 12:00', '구름많음'), ('A02', '2018-02-28 00:00', '구름많음'), ('A02', '2018-02-28 12:00', '구름많음'), ('A01', '2018-03-01 00:00', '구름조금'), ('A01', '2018-03-02 00:00', '구름조금'), ('A01', '2018-03-03 00:00', '구름조금')]

13

[('A02', '2018-02-24 00:00', '구름조금'), ('A02', '2018-02-24 12:00', '구름많음'), ('A02', '2018-02-25 00:00', '구름많음'), ('A02', '2018-02-25 12:00', '구름많음'), ('A02', '2018-02-26 00:00', '구름조금'), ('A02', '2018-02-26 12:00', '구름조금'), ('A02', '2018-02-27 00:00', '구름많음'), ('A02', '2018-02-27 12:00', '구름많음'), ('A02', '2018-02-28 00:00', '구름많음'), ('A02', '2018-02-28 12:00', '구름많음'), ('A01', '2018-03-01 00:00', '구름조금'), ('A01', '2018-03-02 00:00', '구름조금'), ('A01', '2018-03-03 00:00', '구름조금')]

13

[('A02', '2018-02-24 00:00', '구름조금'), ('A02', '2018-02-24 12:00', '구름많음'), ('A02', '2018-02-25 00:00', '구름많음'), ('A02', '2018-02-25 12:00', '구름많음'), ('A02', '2018-02-26 00:00', '구름조금'), ('A02', '2018-02-26 12:00', '구름조금'), ('A02', '2018-02-27 00:00', '구름많음'), ('A02', '2018-02-27 12:00', '구름많음'), ('A02', '2018-02-28 00:00', '구름많음'), ('A02', '2018-02-28 12:00', '구름많음'), ('A01', '2018-03-01 00:00', '구름조금'), ('A01', '2018-03-02 00:00', '구름조금'), ('A01', '2018-03-03 00:00', '구름조금')]

13

[('A02', '2018-02-24 00:00', '구름조금'), ('A02', '2018-02-24 12:00', '구름많음'), ('A02', '2018-02-25 00:00', '구름많음'), ('A02', '2018-02-25 12:00', '구름많음'), ('A02', '2018-02-26 00:00', '구름조금'), ('A02', '2018-02-26 12:00', '구름조금'), ('A02', '2018-02-27 00:00', '구름많음'), ('A02', '2018-02-27 12:00', '구름많음'), ('A02', '2018-02-28 00:00', '구름많음'), ('A02', '2018-02-28 12:00', '구름많음'), ('A01', '2018-03-01 00:00', '구름조금'), ('A01', '2018-03-02 00:00', '구름조금'), ('A01', '2018-03-03 00:00', '구름조금')]

13

[('A02', '2018-02-24 00:00', '구름조금'), ('A02', '2018-02-24 12:00', '구름많음'), ('A02', '2018-02-25 00:00', '구름많음'), ('A02', '2018-02-25 12:00', '구름많음'), ('A02', '2018-02-26 00:00', '구름조금'), ('A02', '2018-02-26 12:00', '구름조금'), ('A02', '2018-02-27 00:00', '구름많음'), ('A02', '2018-02-27 12:00', '구름많음'), ('A02', '2018-02-28 00:00', '구름많음'), ('A02', '2018-02-28 12:00', '구름많음'), ('A01', '2018-03-01 00:00', '구름조금'), ('A01', '2018-03-02 00:00', '구름조금'), ('A01', '2018-03-03 00:00', '구름조금')]

13



1
2
3
4
5
6
7
8
9
10
11
def findLoc():
    for loc in locations:
        items = re.findall(r'<mode>(.+?)</mode>.+?<tmEf>(.+?)</tmEf>.+?<wf>(.+?)</wf>', loc, re.DOTALL)
        # print(items)
        # print(len(items))
 
        for item in items:
            print(item)
 
 
findLoc()
cs


>> 실행결과의 일부


('A02', '2018-02-28 12:00', '구름많고 비')

('A01', '2018-03-01 00:00', '구름많음')

('A01', '2018-03-02 00:00', '구름많음')

('A01', '2018-03-03 00:00', '구름많음')



1
2
for mode, tmEf, wf in items:
    print(mode, tmEf, wf)
cs


>> 이런식으로도 가능하다.



1
2
3
4
5
6
7
8
9
def findLoc2():
    for loc in locations:
        items = re.findall(r'<mode>(.+?)<.+?>.+?<.+?>(.+?)<.+?>.+?<.+?>(.+?)<.+?>', loc, re.DOTALL)
 
        for mode, tmEf, wf in items:
            print(mode, tmEf, wf)
 
 
findLoc2()
cs


>> 이런식으로도 가능하다.

>> 맨 앞에 <mode> 를 남긴 이유는 그 상위 데이터가 더 존재하므로...




'Language > Python' 카테고리의 다른 글

<3-2> Set 과 Dictionary  (0) 2018.03.02
<3-1> 파일 입출력  (0) 2018.02.23
<2-2> 리스트, 튜플  (0) 2018.02.15
<2-1> 제어문과 반복문의 연결고리  (0) 2018.02.06
<1-7> 정규표현식 with Python  (0) 2018.02.03



# Day_02_02_list.py


- Collection 

[] : list

() : tuple

{} : set/dictionary

<> : not used



- list


1
2
3
4
5
6
= [135]
print(a)    # [1, 3, 5]
print(a[0], a[1], a[2])     # 1 3 5
 
a[0= 99
print(a)    # [99, 3, 5]
cs


>> 1 : list 의 선언

>> python 에서는 array 가 없다고 함.

>> 3 : 인덱스를 통한 접근

>> 5 : 값의 변경



- 반복문을 통한 접근


1
2
for i in range(len(a)):
    print(a[i])
cs


>> len(a) : list 의 갯수를 리턴해준다.



- 문제

- 100 보다 작은 난수 10개로 이루어진 리스트를  반환하는 함수 만들기


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def makeRandom1():
    a = [0000000000]
    for i in range(10):
        a[i] = random.range(100)
    return a
 
 
def makeRandom2():
    a = [0]*10
    for i in range(10):
        a[i] = random.range(100)
    return a
 
 
def makeRandom3():
    a = []
    for i in range(10):
        a.append(random.randrange(100))
    return a
cs


>> makeRandom3() 에서 처럼 append() 를 많이 쓴다고 한다.

>> 하지만 느리다고 한다.

>> append() 는 리스트의 맨 뒤에 내용을 추가.



- 문제

- 리스트를 거꾸로 뒤집는 함수 만들기


1
2
3
4
5
def reverseList(c):
    size = len(c)
    for i in range(size//2):
       c[i], c[size-1-i] = c[size-1-i], c[i]
    return c
cs




1
2
for i in a:
    print(i, end=' ')
cs


>> 여기서 a는 리스트

>> i는 인덱스가 아닌, 리스트의 각 요소



- range() 와 리스트의 타입


1
2
3
print(type(range(5)), type(a))  
 
# <class 'range'> <class 'list'>
cs


>> range, list 는 utterable 객체



- reversed(obj)


1
2
3
4
5
6
7
8
9
for i in a:
    print(i, end=' ')
print()
# 37 67 44 50 25 65 15 66 5 86 
 
for i in reversed(a):
    print(i, end=' ')
print()
# 86 5 66 15 65 25 50 44 67 37
cs


>> list 가 뒤집어진 상태로 진행이 된다.


1
2
3
4
for i in reversed(range(len(a))):
    print(a[i], end=' ')
print()
# 86 5 66 15 65 25 50 44 67 37 
cs


>> 이런식으로도 가능하다.



- enumerate()


1
2
3
4
for i in enumerate(a):
    print(i, end=' ')
print()
# (0, 37) (1, 67) (2, 44) (3, 50) (4, 25) (5, 65) (6, 15) (7, 66) (8, 5) (9, 86) 
cs


>> i는 (index, value) 의 형태를 갖는다. 데이터 타입은 튜플..!!

>> 특정 데이터가 몇번째 데이터인지 알고 싶을 때 enumerate() 을 사용


1
2
3
4
for i in enumerate(a):
    print(i[0], i[1], end=' ')
print()
# 0 37 1 67 2 44 3 50 4 25 5 65 6 15 7 66 8 5 9 86 
cs


>> 괄호를 없애고 싶을 땐 인덱스를 활용한다.



- 튜플(tuple)은 리스트의 상수버전...

- 리스트와 사용방법이 동일하다. 다만, 내용을 바꿀수 없을 뿐..!!


1
2
3
= (123)
t[0= 99
# TypeError: 'tuple' object does not support item assignment
cs

 

>> 튜플은 보통 파이썬이 사용한다.

>> 매개변수를 전달하거나, 반환값을 전달할 때.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def sumOfOddEven():
    odd, even = 00
    for i in range(1100):
        if i%2 == 1: odd  += i
        else :       even += i
 
    return odd, even
 
 
s1, s2 = sumOfOddEven()
print(s1, s2)       # 2500 2450
 
= sumOfOddEven()
print(s)            # (2500, 2450)
print(type(s))      # <class 'tuple'>
cs


>> 13 : s 의 타입은 튜플이다.


1
2
3
= 12
print(t)            # (1, 2)
print(type(t))      # <class 'tuple'>
cs



- 그래서 enumerate() 이런식으로 사용한다.


1
2
3
for i, k in enumerate(a):
    print(i, k, end=' ')
print()
cs




- list 로 강제 캐스팅하기


1
2
= list(range(0102))
print(a)    # [0, 2, 4, 6, 8]
cs



- 레퍼런스

 

1
2
3
4
5
6
7
= list(range(0102))
print(a)    # [0, 2, 4, 6, 8]
 
= a;
a[0= 99
print(a)    # [99, 2, 4, 6, 8]
print(b)    # [99, 2, 4, 6, 8]
cs


>> 6 번 라인의 결과는 명확하다.

>> 7 번 라인의 결과는..???

    레퍼런스 개념으로 a와 b는 같은 리스트를 가리킨다..!!

>> 4 번 라인을 얕은복사 라고 한다. (shallow copy)

>> 데이터가 같이 바뀌므로 주의해야한다.



- 데이터의 복사 (깊은복사)


1
2
3
4
5
6
7
= list(range(0102))
print(a)    # [0, 2, 4, 6, 8]
 
= a.copy();
a[0= 99
print(a)    # [99, 2, 4, 6, 8]
print(c)    # [0, 2, 4, 6, 8]
cs


>> copy() 를 사용한다.



- 음수 인덱스


1
2
3
= list(range(0102))
print(a)    # [0, 2, 4, 6, 8]
print(a[0], a[-1])      # 0 8
cs


>>  파이썬은 음수 인덱스를 지원한다. -1은 마지막 값, -2은 뒤에서 두번째 값

동영상 강의 : http://pythonkim.tistory.com/notice/77


# Day_02_01_loop.py



# 제어문과 반복문의 연결고리


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# 문제
# count 에 0~3 사이의 숫자를 입력 받아서
# 입력받은 숫자 만큼 아침인사를 해봅니다.
# 2가지 종류의 코드를 만들어보기.
 
 
def ans1():
    count = int(input('count : '))
 
    if count == 1:
        print("Good Morning!")
    elif count == 2:
        print("Good Morning!")
        print("Good Morning!")
    elif count == 3:
        print("Good Morning!")
        print("Good Morning!")
        print("Good Morning!")
 
 
def ans2():
    count = 2
    if count >= 1:
        print("Good Morning!")
    if count >= 2:
        print("Good Morning!")
    if count >= 3:
        print("Good Morning!")
 
 
def ans3():
    count = 2
    i = 0
    if i < count:
        print("Good Morning!")
        i += 1
        if i < count:
            print("Good Morning!")
            i += 1
            if i < count:
                print("Good Morning!")
                i += 1
                if i < count:
                    print("Good Morning!")
                    i += 1
                    if i < count:
                        print("Good Morning!")
                        i += 1
 
 
def ans():
    count = 3
    i = 0
    while i < count:
        print("Good Morning!")
        i += 1
 
cs




- 규칙


# 규칙을 찾는 것이 중요. (시작, 종료, 증감)

# 1 3 5 7 9     1~9 까지 2칸씩 건너뛴다.

# 0 1 2 3 4     0~4 까지 1칸씩 건너뛴다.

# 5 4 3 2 1     5~1 까지 -1칸씩 건너뛴다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def rule1():
    i = 1                   # 시작
    while i <= 9:           # 종료
        print("Hello")
        i += 2              # 증감
 
 
def rule2():
    i = 0
    while i <= 4:
        print("Hello")
        i += 1
 
 
def rule3():
    i = 5
    while i >= 1:
        print("Hello")
        i -= 1
cs


>> Python 에서는 i++ 과 같은 증감 연산자를 제공하지 않는다고 한다. ㅜㅜ

>> 세 개 모두 "Hello" 를 5번 출력한다.



- 줄이 바뀌지 않게 하기


1
2
3
4
5
rint('Hello', end=' ')
print('python')
 
# 실행결과 
# Hello python
cs


>> end 파라미터를 사용하면 된다.


- end 파라미터의 또 다른 예시.


1
2
3
4
5
print('Hello', end='***')
print('python')
 
# 실행결과
# Hello***python
cs



-  문제


# 0 ~ 99 까지 출력하는 함수를 만드시오.


1
2
3
4
5
def show100():
    i = 0
    while i <= 99:
        print(i, end=' ')
        i += 1
cs




- for in 문 


1
2
3
4
5
6
7
8
9
10
11
12
13
for i in range(0101):
    print(i, end=' ')
print()
 
for i in range(010):
    print(i, end=' ')
print()
 
for i in range(10):
    print(i, end=' ')
print()
 
# 0 1 2 3 4 5 6 7 8 9 
cs


>> 시작 : 0, 종료 : 10, 증감 : 1

>> 시작, 종료, 증감이 명확한 경우 for 문을 사용한다.

>> 증감의 기본은 1, 시작의 기본은 0



# 문제

# count 에 0~3 사이의 숫자를 입력 받아서

# 입력받은 숫자 만큼 아침인사를 해봅니다.

# 2가지 종류의 코드를 만들어보기.


1
2
3
4
5
6
7
8
9
10
11
def sumOfOddEven():
    odd, even = 00
    for i in range(1100):
        if i%2 == 1: odd  += i
        else :       even += i
 
    return odd, even
 
 
s1, s2 = sumOfOddEven()
print(s1, s2)       # 2500 2450
cs



# 난수


1
2
3
4
5
import random
 
print(random.randrange(10))
print(random.randrange(1020))
print(random.randrange(10202))
cs


>> random 모듈을 import 한다.

>> randrange() 는 range() 와 같이 3가지의 종류의 파라미터를 갖는다.

>> 5 줄의 경우 [10, 20) 에서 2씩 증가하는 수들 중에서 난수가 발생함.



# placeholder


1
2
for _ in range(5):
    print(random.randrange(10), end=' ')
cs


>> for i in range(5): 라고 썼을 때, i 를 사용하지 않는다.

>> 하지만 i 를 지우면 에러.

>> 필요가 없는 변수로 의미를 약화시킬 수 있음. _ 로 표현 (placeholder)

>> _ 는 변수이지만 변수로 사용하지 않겠다는 의미..



# random.seed(1)


1
2
3
random.seed(1)
for _ in range(5):
    print(random.randrange(10), end=' ')    # 2 9 1 4 1
cs


>> 난수값을 고정시킬 수 있다.

>> seed 가 1이 되고 나서의 첫번째 숫자, 두번째 숫자 ...

>> 프로그램 처음에 딱 한번 호출해서 사용한다.



1
2
3
4
5
next = 1
def rand():
    global next
    next = next * 1103515245 + 12345
    return int(next // 65536) % 32768
cs


>> seed() 의 원리 같은 코드라고 한다.







### Day_01_05_re.py


동영상 강의 : http://pythonkim.tistory.com/notice/77



- import re 를 해주어야 한다.


- Google 에서 "3412 bob 123" 검색 

>> http://www.linuxfocus.org/Korean/July1998/article53.html 에서 db 데이터 가져올 수 있음.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import re
 
db = '''3412    Bob 123
3834  Jonny 333
1248   Kate 634
1423   Tony 567
2567  Peter 435
3567  Alice 535
1548  Kerry 534'''
 
print(db)
 
# 3412    Bob 123
# 3834  Jonny 333
# 1248   Kate 634
# 1423   Tony 567
# 2567  Peter 435
# 3567  Alice 535
# 1548  Kerry 534
 
 
ns = re.findall(r'[0-9]', db) # 숫자
print(ns)
 
# ['3', '4', '1', '2', '1', '2', '3', '3', '8', '3', '4', '3', '3', '3', '1', '2', '4', '8', '6', '3', '4', '1', '4', '2', '3', '5', '6', '7', '2', '5', '6', '7', '4', '3', '5', '3', '5', '6', '7', '5', '3', '5', '1', '5', '4', '8', '5', '3', '4']
 
 
ns = re.findall(r'[0-9]+', db) # 숫자 한개 이상
print(ns)
 
# ['3412', '123', '3834', '333', '1248', '634', '1423', '567', '2567', '435', '3567', '535', '1548', '534']
cs



# 문제

# 이름만 찾아보기


1
2
3
4
5
6
7
# 문제
# 이름만 찾아보기
# names = re.findall(r'[a-zA-Z]+', db)
names = re.findall(r'[A-Z][a-z]+', db)  # 처음 대문자 한글자 + 소문자 한개 이상.
print(names)
 
# ['Bob', 'Jonny', 'Kate', 'Tony', 'Peter', 'Alice', 'Kerry']
cs


>> [A-Za-z]+ 와 [A-Z][a-z]+ 는 다르다..!!



# 문제

# T로 시작하는 이름

# T로 시작하지 않는 이름


1
2
3
4
5
6
7
8
9
10
11
12
# 문제
# T로 시작하는 이름
# T로 시작하지 않는 이름
 
Tname = re.findall(r'T[a-z]+', db)
print(Tname)    # ['Tony']
 
nTname = re.findall(r'[^T][a-z]+', db)  # bug
print(nTname)   # ['Bob', 'Jonny', 'Kate', 'ony', 'Peter', 'Alice', 'Kerry']
 
nTname = re.findall(r'[A-SU-Z][a-z]+', db)
print(nTname)   # ['Bob', 'Jonny', 'Kate', 'Peter', 'Alice', 'Kerry']
cs


>> T로 시작하지 않는 단어 중 [^T][a-z] 로 했을 때 문제가 있었다.

>> 바로 'ony' 라는 단어까지 검색이 되어버렸다.



# raw string


r'string' : raw


- 파이썬에서 사용하는 문자열로 일반 문자열과 충돌을 막기 위해 제공하는 것 같다 .

- 정규표현식 외에 쓸일은 없다고 한다.



'Language > Python' 카테고리의 다른 글

<2-2> 리스트, 튜플  (0) 2018.02.15
<2-1> 제어문과 반복문의 연결고리  (0) 2018.02.06
<1-6> 정규표현식 (Regular Expression)  (0) 2018.02.02
<1-5> 함수(function)  (0) 2018.02.01
<1-4> 제어문(if)  (0) 2018.01.31

### 정규표현식


- 특정한 규칙을 가진 문자열의 집합을 표현

- 문자열의 검색과 치환을 위해 지원.



POSIX 기본 및 확장 표준 문법

메타문자기능설명
.문자1개의 문자와 일치한다. 단일행 모드에서는 새줄 문자를 제외한다.
[ ]문자 클래스"["과 "]" 사이의 문자 중 하나를 선택한다. "¦"를 여러 개 쓴 것과 같은 의미이다. 예를 들면 [abc]d는 ad, bd, cd를 뜻한다. 또한, "-" 기호와 함께 쓰면 범위를 지정할 수 있다. "[a-z]"는 a부터 z까지 중 하나, "[1-9]"는 1부터 9까지 중의 하나를 의미한다.
[^ ]부정문자 클래스 안의 문자를 제외한 나머지를 선택한다. 예를 들면 [^abc]d는 ad, bd, cd는 포함하지 않고 ed, fd 등을 포함한다. [^a-z]는 알파벳 소문자로 시작하지 않는 모든 문자를 의미한다.
^처음문자열이나 행의 처음을 의미한다.
$문자열이나 행의 끝을 의미한다.



양의 지정
?물음표는 0번 또는 1차례까지의 발생을 의미한다. 이를테면 colou?r는 "color"와 "colour"를 둘 다 일치시킨다.
*별표는 0번 이상의 발생을 의미한다. 이를테면 ab*c는 "ac", "abc", "abbc", "abbbc" 등을 일치시킨다.
+덧셈 기호는 1번 이상의 발생을 의미한다. 이를테면 ab+c는 "abc", "abbc", "abbbc" 등을 일치시키지만 "ac"는 일치시키지 않는다


출처 : Wiki (https://ko.wikipedia.org/wiki/정규_표현식)



### Regex Crossword (https://regexcrossword.com/) ###


- Regular Expression 을 crossword 퍼즐을 통해 익힐 수 있게 도와주는 사이트


- Tutorial Play 을 통해 기본적인 학습을 할 수 있다.


Ex)

- (A)\1 에서 ( )\ 는 한 쌍..!! 여기서 \ 의 뜻은 ( )의 인덱스. ( )는 9개까지 쓸 수 있다.

- A{2, } : 두 번 이상.

- A{1} : 한 번.

- \s 는 공백



- Beginner 등을 통해 연습을 할 수 있다.


Ex)

- .* : 아무 글자. 있어도 되고 없어도 되고.

- M? : M이 하나 있거나 없거나.

- / 는 문자. \ 는 의미가 있다.

- *가 [] 안에 들어가면 단순 문자. >> [*]

- \d : 숫자, [0-9] 와 동일

- \D : 숫자가 아닌 것들.







'Language > Python' 카테고리의 다른 글

<2-1> 제어문과 반복문의 연결고리  (0) 2018.02.06
<1-7> 정규표현식 with Python  (0) 2018.02.03
<1-5> 함수(function)  (0) 2018.02.01
<1-4> 제어문(if)  (0) 2018.01.31
<1-3> 연산자  (0) 2018.01.30

동영상 강의 : http://pythonkim.tistory.com/notice/77



# Day_01_04_Function.py



# Function


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# 함수의 핵심 : 데이터를 넘겨주고 넘겨받기
# 매개변수 : 넘겨주는 데이터
# 리턴값 : 넘겨받는 데이터
 
 
# 매개변수 없고, 반환값도 없고.
def f1():
    print('f1')
 
 
f1()    # f1
 
 
# 매개변수 있고, 반환 값 없고
def f2(a, b):
    print('f2', a, b)
 
 
f2(23'abc')   # f2 23 abc
 
 
# 매개변수 없고, 반환 값 있고.
def f3():
    # pass      # 아직 코딩 전이라는 뜻..
    print('f3')
    return 17
 
 
= f3()
print(a)        # 17
print(f3())     # 17
 
 
# 매개변수 있고, 반환 값 있고.
# 두 자리 양수를 거꾸로 뒤집는 함수 만들기
def f4(num):
    return num%10*10 + num//10
 
 
print(f4(25))    # 52
 
 
 
cs



# 문제


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 문제
# 두 개의 정수 중에서 큰 숫자를 찾는 함수
def max2(a, b):
    if(a > b):
        return a
    return b
 
 
print(max2(37))   # 7
print(max2(73))   # 7
 
 
# 문제
# 네 개의 정수 중에서 큰 숫자를 찾는 함수
def max4(a, b, c, d):
    x, y = max2(a, b), max2(c, d)
    return max2(x, y)
 
 
print(max4(3917))
cs


>> 함수의 목적은 재사용..!!



'Language > Python' 카테고리의 다른 글

<1-7> 정규표현식 with Python  (0) 2018.02.03
<1-6> 정규표현식 (Regular Expression)  (0) 2018.02.02
<1-4> 제어문(if)  (0) 2018.01.31
<1-3> 연산자  (0) 2018.01.30
<1-2> 파이썬 입문  (0) 2018.01.29