0914 - Python

오늘·2022년 9월 14일
0

A

목록 보기
13/46

복습문제

1. 객체의 형태를 그대로 유지하면서 파일에 저장하고
불러올 수 있게 하는 모듈의 이름은?
[답변]
pickle



2. time에서 포맷코드 :%x는 무엇을 출력하는가?
[답변]
현재 설정된 지역에 기반한 날짜 출력 



3. list(zip([1, 2, 3], [4, 5, 6]))을 출력했을 때 예상되는 출력물은?
[답변]
[(1, 4), (2, 5), (3, 6)]



4. 아래 리스트를 map 함수 사용하여 다음과 같이 바꾸세요
[리스트]
a = ['3', '5', '18', '11']
[바꿀 리스트]
['3개', '5개', '18개', '11개']
[답변]
list(map(lambda x: x + '개', a)) 



5. 1부터 55까지의 수 중에서
random 으로 10개의 수를 뽑아 리스트를 만들어라., 리스트 내 수들은 중복되지 않아야 한다.
[답변]
import random
i = 0
sNum = []
i = 1
while i < 10+1 :
    a = random.randint(1, 55)
    if a not in sNum :
        sNum.append(a)
        i += 1
    else :
        continue
print(sNum)
[질문 답변]
while len(li) < 10 :
	a = random.randint(1, 55)
    if a not in li :
    	li.append(1)



6. sys모듈 중 명령행에서 인수를 전달하면
어떤 변수에 저장되는가?
[답변] sys.argv[]


7. random 함수를 사용하여 [1, 2, 3, 4, 5] 리스트를
섞어주세요
[답변]
a = [1, 2, 3, 4, 5]
random.shuffle(a)



8. 현재 월//년과 시간을 출력하세요
[답변]
[질문 답변]
time.strftime('%x, %x', time.localtime())



9. 각 속성별로 데이터를 저장한 리스트 들이 있다.
세 리스트마다의 데이터를 각각 속성값으로 나누어
하나의 데이터열로 만드는 새로운 리스트 info를
만들어 주세요
[리스트]
name = ['Lee', 'Park', 'Jeon', 'Choi']
age = [19, 22, 16, 31]
job = ['student', 'teacher', 'student', 'artist']
[답변]
info = list(zip(name, age, job))



10. 김밥천국메뉴.csv 파일을 읽은 후
1) 가격이 5000원 이상인 메뉴를 출력하세요.
2) 김밥류의 가격 평균을 구해보세요
[질문 답변]
1) df[df['가격']>=5000].메뉴
2) df[df['종류'] == '김밥']['가격'].mean() 

문제

하위 디렉토리에 있는 py파일을 검색하는 함수 만들기 (jupyter lab)

import os

def search(dirname) :
	# file 디렉토리 명을 받아서 하위 파일 이름들 filenames로 넣어주기
    filenames = os.listdir(dirname)
    
    # 받아온 파일이름들을 하나씩 돌려줄건데
    for filename in filenames :
    	# full_filename은 디렉토리명+파일이름(join)
        full_filename = os.path.join(dirname, filename)
        
        # 만약 full_filename에 하위파일들이 있다면
        if os.path.isdir(full_filename) :
        	# 다시 이 함수를 호출(재귀)
            search(full_filename)
        
        # 하위 파일이 없다면
        else :
        	# 확장자를 찾아서
            ext = full_filename[-3:]
            # .py라면 full_filename을 출력
            if ext == ".py" :
                print(full_filename)


# 함수 호출
search("Downloads")
> Downloads\tabto4.py

🌱 정규표현식

정규식을 연습하거나 테스트를 해볼 수 있다 ( RegExr )

re 모듈

re모듈은 파이썬을 설치할 때 자동으로 설치되는 기본 라이브러리 이다.

import re
p = re.compile()

re.compile() 을 사용하여 정규 표현식을 컴파일합니다.

정규 표현식을 사용한 문자열 검색

메서드 목적
match() 문자열의 처음부터 정규식과 매치되는 지 조사한다
search() 문자열 전체를 검색하여 정규식과 매치되는지 조사한다
findall() 정규식과 매치되는 모든 문자열을 리스트로 돌려준다
finditer() 정규식과 매치되는 모든 문자열을 반복가능한 객체로 돌려준다
# 각각의 예시를 확인하기 위해 먼저 패턴하나를 만들어 놓자
import re
p = re.compile('[a-z]+')

match()

match의 결과로 match 객체 또는 None을 돌려주기 때문에 사용시 다음과 같은 흐름으로 작성할 수 있다.

m = p.match("python")
print(m)
> <re.Match object; span=(0, 6), match='python'>
# 위처럼 정규식에 부합되면 match객체를 돌려준다.
# 부합되지 않으면 None 아무것도 나오지 않는다
m = p.search("python")
print(m)
> <re.Match object; span=(0, 6), match='python'>

match와 마찬가지로 동일하게 매치된다. match()와 다른점은 문자열의 처음부터 검색하는 것이 아니라 문자열 전체를 검색하기 때문에

m = p.match("3 python")
n = p.search("3 python")
print(m)
print(n)

> None
> <re.Match object; span=(2, 8), match='python'>

위와 같은 차이가 있기때문에 문자열의 처음부터 검색할지의 여부에 따라 선택하여 사용해야 한다.

findall

m = p.findall("life is too short")
print(m)
> ['life', 'is', 'too', 'short']

문자열의 단여를 각각 정규식과 매치하여 리스트로 돌려준다

re.compile() 하지 않고

정규표현식을 확인해 볼 수 있는 방법이 있다.

>>> p = re.compile('[a-z]+')
>>> m = p.match("python")
# 지금까지 위와 같이 사용했지만

>>> m = re.match('[a-z]+', "python")
# 이와같은 한줄로도 동일한 결과를 얻을 수 있다

# 한 번 만든 패텬 객체를 여러번 사용해야할 때는 re.compile 을 사용하는 것이
몇 번 수행하지 않을 거라면 한줄로 표현하는 것이 좋을 듯 하다.

기초, 메타문자

메타문자 : 원래 그 문자가 가진 뜻이 아닌 특별한 용도로 사용하는 문자를 말한다.

. ^ $ * + ? {} [] \ | ()

문자 클래스

[]안의 두 문자 사이 하이픈(-)은 범위를 의미한다. 예를들어 [a-c] = [abc] 이고 [0-3] = [0123] 인 것이다.

주의해야 할 메타문자는 ^으로 이는 반대(not)의 의미를 가진다. 예를 들어 [^0-9]는 0에서 9까지를 제외한 모든 문자를 뜻하게 되는 것이다.

자주 사용하는 문자 클래스

\d : 숫자와 매치,[0-9]와 동일한 표현식
\D : 숫자가 아닌것돠 매치, [^0-9]와 동일
\s : whitespace문자(=space 나 tab과 같이 공백을 표현하는 문자) 와 매치
	즉 [\t\n\r\f\v] 와 동일
\S : whitespace 문자가 아닌 것과 매치
\w : 문자+숫자와 매치, [a-zA-Z0-9_]와 동일
\W : 문자+숫자가 아닌 문자와 매치

Dot(.)

줄바꿈 문자인 \n을 제외한 모든 문자와 매치됨을 의미한다.

예를 들어 a.b는 a와 b사이에 어떤 문자라도 들어가 있으면 매치된다

[정규식] a.b
aab : 매치 o
a5b : 매치 o
abe : 매치 x - a와 b사이에 어떤 문자도 끼어있지 않으므로
aaab : 매치 x - a와 b사이에 두개나 끼어있어

단, a[.]b는 말그대로 a와 b사이에 점(.)이 들어있어야 매치된다.

반복

( * )

바로 앞에있는 문자가 0개부터 약 2억개 정도 반복되어도 매치된다는 것을 의미한다.

'''
('do*g') 는
dg : 매치 o
dog : 매치 o
dooog : 매치 o
dooooooooooooooooog : 매치 o
dogg : 매치 x
'''

# 확인을 위해 match 해보기
import re
p = re.compile('do+g')
m = p.match("dg")
> <re.Match object; span=(0, 3), match='dog'>

( + )

최소 1번 이상 반복될 때 사용한다.

'''
('ca+t') 는
ct : 매치 x
cat : o
caat : o
'''

p = re.compile('ca+t')
m = p.match("catt")
m
> <re.Match object; span=(0, 3), match='cat'>

m = p.match("ct")
m
> # 매치되는 것이 없어서 아무것도 나오지 않는다.

({m, n}, ?)

만약 반복 횟수를 제한하고 싶다면 사용한다. m부터 n까지 매치하는 것으로 m아니 n을 생략할 수도 있다. {,3} 이면 반복횟수가 0부터 3이하 {3,} 이라면 반복횟수가 3이상부터 무한대인 경우이다.

{1, } 은 +와 동일하고
{0,}은 *와 동일하다

ca{2}t : a가 2번 반복되면 매치
cat{2, 5} : t가 2~5번 반복되면 매치

비슷한 것으로 ? 도 있다. 이는 {0, 1}을 의미
=> 0번 즉, 없어도 매치된다

do?g : o가 0~1 번 반복되면 매치

sub()

sub("바꿀 문자열", "대상 문자열")
정규식과 매치되는 부분을 다른 문자로 쉽게 바꿀수 있다.

p = re.compile('(blue|white|red)')
p.sub('colour', 'blue socks and red shoes')
> 'colour socks and colour shoes'

compile에 넣은 blue 또는 white 또는 red 라는 문자열이 모두 바뀌는 것을 확인 할수 있다. 그런데 만약 바꾸기 횟수를 제어하려면 세번째 매개변수로 count값을 넘기면된다.

p.sub('colour', 'blue socks and red shoes', count=1)
> ''colour socks and red shoes'

문제

1) li 리스트를 변경해보자

li = ["", "1", "12", "123", "1234", "abc", "la"]

# sub
for string in li : 
    # 숫자만큼 A 추가하기
    print(re.sub(r"[0-9]", "A", i), end = ", ")

> , A, AA, AAA, AAAA, abc, la,



for string in li : 
    # 4자리 숫자인 것만 A로 바꾸기
    print(re.sub(r"[0-9]{4}", "A", string), end = ", ")
> , 1, 12, 123, A, abc, la, 



for string in li : 
    # 시작이 숫자면 A로 바꾸겠다
    print(re.sub(r"^[0-9]", "A", string), end = ", ")
> , A, A2, A23, A234, abc, la, 



for string in li : 
    # 끝나는 부분이 숫자인 것을 A로 바꾸겠다
    print(re.sub(r"[0-9]$", "A", string), end = ", ")
> , A, 1A, 12A, 123A, abc, la,



for string in li : 
    # 숫자가 아닌것만 A로 바꾸겠다
    print(re.sub(r"[^0-9]", "A", string), end = ", ")
> , 1, 12, 123, 1234, AAA, AA, 
  1. li2 리스트를 변경해보자
# A로 시작하고 O로 끝나는 사이에 두개의 문자가 있는 경우
# #으로 변경하세요
for string in li2 :
    # print(re.sub("a..o", "#", string), end = ", ")
    # print(re.sub("a.{2}o", "#", string), end = ", ")
    print(re.sub("^[a].{2}[o]$", "#", string), end = ", ")
> #, #, aBo, a123o, kbs, 123kbs, KBS, KB3, abcKBS123, 




# 알파벳 대문자로 시작하고 숫자로 끝나는 경우
for string in li2 :
    # print(re.sub("^[A-Z].*[0-9]$", "#", string), end = ", ")
    # \S = 공백이 아닌 뭔가 들어있는 경우
    print(re.sub("^[A-Z]\S[0-9]$", "#", string), end = ", ")
> a12o, abco, aBo, a123o, kbs, 123kbs, KBS, #, abcKBS123, 




# 123을 찾아서 바꾸기
for string in li2 :
    print(re.sub("123+", "#", string), end = ", ")
> a12o, abco, aBo, a#o, kbs, #kbs, KBS, KB3, abcKBS#, 




# 문자 중간에 있는 123 찾기
for string in li2 :
    # print(re.sub("^\w123\w$", "#", string), end = ", ")
    # print(re.sub("\S123\S", "#", string), end = ", ")
    print(re.sub(".+123.+", "#", string), end = ", ")
> a12o, abco, aBo, #, kbs, 123kbs, KBS, KB3, abcKBS123, 



# - 뒤에 있는 부분을 모두 *로 변경
string = "park 800905-1049118 Kim 700905-1059119" 
# re.sub('\d{7}','*******',string)
# re.sub("-\S+", "-*******", string)
re.sub("-\d{7}", "-*******", string)
> 'park 800905-******* Kim 700905-*******'

문제

1) 문자열 바꾸기

# a:b:c:d 문자열을 split와 join함수를 사용하여
# a#b#c#d 와 같이 변경하세요
a = "a:b:c:d"
a = a.split(":")
a = "#".join(a)
a

2) 딕셔너리 값 추출하기

# a 딕셔너리에는 'C'라는 key가 없으므로 오류가 발생한다
# C에 해당하는 key 값이 없을 경우 오류 대신 70을 얻을 수 있도록 수정하시오
a = {'A':90, 'B':80}
try :
    a['C']
except :
    print(70)

3) 리스트 총합 구하기

# 다음 리스트에서 50점 이상 점수의 총합을 구하시오
A = [20, 55, 67, 82, 45, 33, 90, 87, 100, 25]
for i in A :
    if i < 50 :
        A.remove(i)
result = sum(A)
result

4)

0개의 댓글