Python's very basic

Python's very basic

2016, Sep 25    

◈ Python

1. 파이썬?


파이썬이란 1990년 암스테르담의 귀도 반 로섬(Guido Van Rossum)에 의해 만들어진 인터프리터 언어이다.
귀도는 이 파이썬이라는 이름을 본인이 좋아하는 “Monty Python’s Flying Circus”라는 코미디 쇼에서 따왔다고 한다.

Google.

파이썬 쉘에서 license()함수를 써보면 더 알 수 있다.
파이썬은 스크립트 언어로서 컴파일 언어와 달리 언어의 Syntax에 맞는 파일을 인터프리터가 라인마다 해석을 해서 실행한다.
그래서 작성 및 디버깅이 상대적으로 간편하다는 장점이 있다.

인터프리터 언어(스크립트 언어)의 쉘을 REPL이라고도 한다.
REPL은 _‘Read-Eval-Print-Loop’_의 약자로서 interactive하게 사용자의 단일 명령을 받아들이고, 그것을 평가해서 그 값을 사용자게 반환하는 역할을 한다.
REPL에서는 명령이 줄 단위(piecewise)로 실행된다.

REPL의 마지막에 왜 L(loop)이 들어갈까 고민했는데 사용자가 파이썬 쉘을 종료하기 전까지 이전까지의 과정을 반복하기 때문이라고 생각한다.
Wikipedia



2. 파이썬의 자료타입


자바를 공부했을 당시 기본 타입 8개(숫자, 문자, 부울 값 등)를 먼저 배우고 배열 등을 배운 기억이 있다.
그러나 파이썬은 모든 것이 클래스의 인스턴스라고 한다. 정수, 문자열도 마찬가지다. 천천히 살펴본다.

2.1 int

말 그대로 정수이다. ok = 2라고 하면 정수 2를 ok라는 변수에 대입하는 것이 된다.

2.2 str

문자열이다. 파이썬은 문자와 문자열에 대한 구분이 없다. 모두 문자열이다.
'ㅁㄴㅇㄹ'와 같이 ''""안에 적는 것은 문자열이 된다.(둘은 구분하지 않는다. 다만 열고 닫을 때는 통일해야 한다.)

2.3 bool

True(참), False(거짓)을 나타내는 부울값이다. 조건식에서 많이 활용한다. help(bool)을 보면 신기하게도 정수를 상속받는다.
True는 1과 같고 False는 0과 같다. 따라서 True * 3이 에러 없이 3이라고 출력된다.

2.4 list

파이썬에서의 리스트는 배열이라고 번역되지만 정확히는 linked-list라고 한다.
그 안에는 무엇이든 들어갈 수 있고 순서가 지켜져야 한다. 그리고 중복을 허용한다.
[ ]안에 값이 들어간다.

animals = ["dog", "cat", "fish", "monkey", "dog"]
print(animals)

>>> ['dog', 'cat', 'fish', 'monkey', 'dog']

위와 같이 정의한다.
첫 번째 인자(‘dog’)부터 0번째 인자로 계산되고(indexing) 만약 인수의 개수가 n개이면 마지막 인수는 n-1번째 인자가 된다.

animals = ["dog", "cat", "fish", "monkey", "dog"]
print(animals[0])
print(animals[4])
print(animals[5])

>>> 'dog'
>>> 'monkey'
>>> 'dog'

위와 같이 리스트 안의 원소에 접근할 수 있다.

또한 리스트는 슬라이싱(list[start:end:stride]처럼 구간 인덱싱)이 가능하다.
start는 시작 위치로 안 적으면 0이 기본값이다. end는 끝 위치로 안 적으면 리스트의 끝이 기본이다.
여기서 주의할 것은 list[:4]와 같이 적으면 4의 인덱스를 갖는 값이 아니라 그 전 값인 3의 인덱스를 갖는 값을 가진다는 것을 알아야 한다.
마지막으로 stride는 건너띄는 정도를 의미한다. 기본값은 1로 그 다음 값을 찾는다.
그런데 만약 2가 된다면 슬라이딩할 때 하나 건너뛰고 값을 찾는다.


animals = ["dog", "cat", "fish", "monkey", "dog"]
animals[1:3]
animals[2:4]
animals[1::2]

>>> ['cat', 'fish']
>>> ['fish', 'monkey']
>>> ['cat', 'monkey', 'dog']


위에서 기억할 건 end위치의 숫자 전까지 슬라이싱 했다는 것과 stride에 2를 넣음으로써 하나씩 건너뛰고 슬라이싱했다는 것이다.
중요하다.


2.5 tuple

튜플은 순서가 있고 중복을 허용한다는 점에서 리스트와 많이 비슷하다.
그러나 ( ) 안에 값이 들어가고 무엇보다 값이 불변이라는 점이 큰 차이점이다.
원소를 추가하거나 지우거나, 원소 값을 지울 수 없다.
하나의 값이 아닌 여러 값을 반환하는 함수들은 그 값을 튜플 안에 넣어 반환한다.

tuple1 = (1, 2, 3, 4, 5)
tuple2 = tuple([1, 2, 3])
tuple3 = 1, 2
tuple4 = (1,)


위와 같이 다양한 방법으로 튜플을 정의할 수 있는데 tuple4의 경우 하나의 원소를 갖는 튜플을 만들 때는 ','를 붙여준다는 것이 특이하다. 그리고 tuple3처럼 여러 값을 하나의 변수에 담으면 그 값들 역시 튜플이 된다.


2.6 set

말 그대로 집합이다. 중고등학교 때 정상적인 수학과정을 이수했다면, 그 집합 개념과 연결시키면 매우 쉽다.
{ }안에 그 값이 들어가고 이 값들은 순서가 없고, 중복을 허용하지 않는다.

중복을 허용하지 않는다는 점에서 리스트 등에서 중복된 값을 없애는 데 사용될 수 있다.


k = [4, 3, 2, 1, 4, 3, 2, 1]
new_set = list(set(k))
print(new_set)

>>> [1, 2, 3, 4]


이 방법을 쓰는 데는 조심해야 한다. 이 리스트는 4, 3, 2, 1이라는 순서를 갖고 있는데 set이라는 함수를 사용함으로써 순서가 사라졌다는 것이다. 이런 활용에는 주의를 요한다.

그리고 집합에서 파생되는 차집합, 합집합, 곱집합 등이 함수로 구현되어 있고 연산자로까지 구현이 된다는 것도 중요한 특징이다. 이건 같이 더 공부하자.

# 차집합 구하기
a = {1, 2, 3, 4, 5}
b = {4, 5, 6, 7, 8}

print(a - b)
>>> {1, 2, 3}


2.7 dict

한국말로 하면 ‘사전’이다. 영한사전을 생각하자. 내가 ‘snow’이라는 단어를 주면 ‘눈’이라는 단어를 내게 알려줄 것이다.
하나의 사전에서 ‘dream’이라는 단어는 굳이 두 개 이상 존재하지 않을 것이다.(다의어는 하나로 보자)
하지만 ‘eye’라는 단어도 ‘눈’이라는 같은 값을 가질 수는 있다. 여기서 착안된 것이 dict 자료구조이다.
dict는 하나의 원소를 key(ex ‘snow’):value(ex ‘눈’), 즉 키:값 쌍으로 저장하는 구조이다.
키는 값에 도달하는 방법이 된다.
키는 여러 값에 대응하면 안 되기 때문에 중복을 허용하지 않지만 값은 중복될 수는 있다. 그리고 원소간 순서가 없다.

참고로 dict 같은 자료구조를 ‘Associative array’라고 한다.

english_dict = {
	'snow': '눈',
	'eye': '눈',
	'english': '영어'
}

print(english_dict['snow'])
print(english_dict['english'])

>>> 
>>> 영어


위와 같이 키를 인덱싱함으로써 값에 접근할 수 있다.

list, tuple, set, dict를 비교하면 다음과 같다.

자료구조 순서 여부 원소의 중복 가능 여부 사용 괄호 예시
list O O [] [1,2,3]
tuple O O () (1,2,3)
set X X {} {1,2,3}
dict X key는 불가능, value는 가능 {} {'a':1, 'b':2, 'c':3}



3. 조건문, 반복문


3.1. 조건문


3.1.1 if

기본적으로 if 조건: 참일 때의 실행문으로 구현할 수 있다.
조건은 True 또는 False 값 중 하나를 반드시 가져야 하며,
False일 때는 실행되지 않는다. else를 넣으면 조건이 거짓일 때 실행되는 실행문을 넣을 수 있다.

여러 언어에서 유명한 if else등은 파이썬에서는 줄여서 elif으로 표현되며,
하나의 조건문에서 여러 개 들어갈 수도 있다. 다만 조건의 마지막은 언제나 else가 되어야 한다.


grade = 80
if grade >= 90:
    print("학점 : A!!")
elif grade >= 80:
    print("학점 : B")
elif grade >= 70:
	print("학점 : C..")
else:
	print("장원 낙제요!")
>>> 학점 : B


많은 프로그래밍 언어 책에서 쓰는 고전 같은 예 중 하나이다. 성적을 받아 그에 맞는 학점을 준다고 할 때, 90점 이상이면 ‘‘A’, 90점 이하일 때 90점 이상이면 ‘B’, 80점 이하일 때 70점 이상이면 ‘C’와 같이 조건문을 만들 수 있다.


if grade >= 90:
    print("학점 : A!!")
else:
	if grade >= 80:
    print("학점 : B")
    else:
	    if grade >= 70:
		print("학점 : C..")
		else:
			print("장원 낙제요!")


같은 내용을 위와 같이 if을 중첩해서 할 수도 있을 것이다.
그러나 import this에서 볼 수 있는 유려한 시 ‘Zen of Python’은 중첩(nested)은 지양해야 한다고 말하고 있다. 보기에도 안 이쁘다.


3.2. 반복문

많은 프로그래밍에서 반복문은 기본적으로 for, while을 지원한다.

3.2.1. for

k = [1, 2, 3, 4, 5]
for i in k:
  print(i)

>>> 1
>>> 2
>>> 3
>>> 4
>>> 5


위와 같이 for value in list 밑에 실행 블록을 적으면 list 안의 value 하나씩을 반복해서 실행할 수 있다.


3.2.2. while

경험적으로 whilefor보다 적게 쓰이는 것 같기는 하다.
for문은 주로 반복을 몇 번 실행할지 알 때 사용하고, while은 몇 번 반복할지 확실하지 않을 때 사용한다.

import random
i = 0
n = random.randint(1, 5)
while i < n:
  print('Hellow World!')
  i += 1


다음과 같이 while을 사용하면 n의 값이 얼마이든지 간에 문제없이 반복문을 실행할 수 있다.



4. 배운 것을 활용해보자!


4.1. Palindrome

Palindrome이란 ‘기러기’처럼 원본과 글자들을 거꾸로 배열한 문자열이 같은 문자열을 의미한다.
forwhile을 활용해 입력된 문자열이 palindrome인지 검사하자.

def is_palindrome(string):
    length = len(string)
    for i in range(len(string)):
        left = string[i]
        right = string[length-1-i]
        
        if left != right:
            return False
    return True

와 같이 작성할 수도 있고,

def is_palindrome(string):
    return string == string[::-1]

처럼 작성할 수도 있다. 여기서 밑에가 더 짧다고 무조건 좋지 않을 수도 있다.
문자열이 매우 길 경우, 중간에라도 값이 출력되는 위의 버전이 더 좋을 수 있기 때문이다.
또한 조금 더 customization한다면 for의 범위를 문자열의 절반까지만 할 수도 있을 것이다.



5. 파이썬의 입출력

파이썬에서 텍스트 파일 등을 열고 작업할 수 있다. 이 때 open 함수를 사용한다.


5.1 파일을 열고 작성할 때 open을!


fp = open("hello.txt", "w")    # 1.
fp.write("hello world")          # 2. 
fp.close()                            # 3. 


  1. open 함수는 인자를 두 개 받는다.
    • 하나는 파일이다. 위에서는 ‘hello.txt’를 받고 있다. 이때 알아야 할 것은 저기에는 경로가 들어간다는 것이다. 경로에는 절대경로와 상대경로가 있는데, 위의 경우는 상대경로다. 해당 파이썬 파일이 있는 곳에 같이 있는 hello.txt 파일을 읽는다는 것이다. 절대 경로는 'C:\Users\darkboy\크큭암흑룡이.txt'와 같이 절대적으로 해당 파일이 존재하는 곳을 명시할 때 사용한다.
    • 두 번째는 여는 모드이다. 'w'는 해당 파일에 내가 입력하겠다는 뜻이다. 'a'와 구별해야 하는데, 'w'는 파일에 다른 내용이 있을 때 완전히 지우고 내용을 적는다면, ‘a’는 기존 내용 뒤에 추가되는 ‘append’모드다. 'r'는 ‘read’모드로 파일을 읽을 수만 있다. open함수에는 ‘r’가 디폴트 값이다. ‘r+’와 같이 적으면 읽고 쓰는 것을 동시에 할 수 있다.
  2. fp를 ‘w’모드에서 열었으니 write함수로 파일 안에 내용을 적을 수 있다.

  3. 파일을 열었으면 꼭 닫아야 한다. 텍스트 파일을 파이썬으로 열고, 동시에 윈도우에서 같이 열었다고 하면 혼선이 생긴다.
    재수 없으면 모든 내용이 삭제될 수도 있으니 꼭 사용 후 닫아줘야 한다.

참고로 fp는 ‘file pointer’의 약자로 어떤 파일을 가리키는지 명시할 때 관습적으로 사용된다.
fpprint에서도 사용가능하니 help(print)를 찾아보자.
pickle, json 등 파일 입출력 모듈을 파이썬 공식문서에서 찾을 때 많이 등장한다.


5.2. 파일을 열고 읽을 때


fp2 = open("./hello.txt") # 1.
lines = fp2.read()         # 2. 
fp2.close()                  # 3. 


  1. open함수의 두 번째 인자에 아무 값도 주지 않았다. 디폴트로 ‘r’모드가 되었고 읽는다는 것이 된다.
  2. read함수를 통해 내용을 전부 읽었다. 전체 파일이 하나의 str로 처리된다. 한 줄씩 리스트에 담는 readline 함수도 존재한다.
  3. 닫아주는 센스..


5.3. with를 사용해서 열자.

with open("hello.txt", "r") as fp:     # 1.
    data = fp.read()
    print(data)
    # 현재 Code Block 내에서만 fp 라는 변수가 존재 
    # Indent 가 끝나면
# 여기로 나오면 => 자동으로 fp.close() 실행
print('my babe')


with문을 사용하면 입출력을 더 편하게 사용할 수 있다. 사람은 닫는 것을 까먹는 실수를 할 수도 있는 것이 아닌가.
이때 with를 사용하면 쉽게 열고 닫을 수 있다. 파일을 원하는 모드로 열고 as를 통해 변수를 지정할 수 있다. 그 안에서 블록을 indent해서 작성하면 블록 내 모든 코드는 파일이 열렸을 때 적용되고 with문을 나오면(indent를 없애면) 자동으로 닫아진다.



6. 심화 문법 조금..

위에서 설명 안 했지만 많은 기본자료형이 본인만의 특수한 메소드를 지원한다. 이 중 중요하고 유용한 기능을 조금만 살펴본다.


6.1. str의 메소드


6.1.1 split

문자열에서 특정 문자열을 기준으로 나눠 리스트로 반환한다.

k = "나는 밥을 먹었다.\n메뉴는 후라이드 옥수수.\n맛있었다.\n그 맛은 뭐랄까, 강냉이 몇 개 나가는 느낌?"
k.split('\n')

>>> ['나는 밥을 먹었다.', '메뉴는 후라이드 옥수수.', '맛있었다.', '그 맛은 뭐랄까, 강냉이 몇 개 나가는 느낌?']


6.1.2. isnumeric

문자열이 숫자인지 증명한다. 숫자를 입력 받아서 연산 등을 해야할 때 필요할 것 같다. 숫자면 True, 아니면 False를 반환한다.

string = input('숫자를 입력해주시죠 : ')
if string.isnumeric():
    print( int(string) + 3)
else:
    print('숫자가 아니네요..')

>>> 숫자를 입력해주시죠 : 33
>>> 36

입력 받은 문자열이 숫자가 아니면 더하기 연산이   것이다.
이런 상황처럼 인풋이 숫자인지 검증할   유용하다. `isalpha`, `isupper`, `islower`  유사한 버전이 많다.
 살펴보자.


6.1.3. join

원소로 받는 리스트 등 iterable한 객체들을 해당 문자열로 이어붙인다. 문자열을 출력한다.

'+'.join(['1','2','3','4','5'])

>>> '1+2+3+4+5'


6.2. list

파이썬에서 가장 많이 사용하는 기본 자료구조는 아마 list일 것이다. 그래서 메소드도 정말 많다. 몇 개만 보자.


6.2.1. append

리스트 끝에 원소를 추가한다.

k = [1, 2, 3, 4,]
k.append(5)
print(k)

>>> [1, 2, 3, 4, 5]


6.2.2. sort

리스트를 정렬할 때 사용한다. 디폴트는 오름차순이다. None을 반환한다.(따로 출력되는 값이 없이 변하기만 한다.)

k  = [5, 4, 3, 2, 1, ]
k.sort()
print(k)

>>> [1, 2, 3, 4, 5, ]

정렬하는 방법을 지정해줄 수도 있다.


l = [('a', 3), ('b', 7), ('c', 1), ('d', -3)]
l.sort(key=lambda x: x[1])
print(l)

>>> [('d', -3), ('c', 1), ('a', 3), ('b', 7)] # 각 인자의 숫자 값을 기준으로 정렬되었다.
내림차순하고 싶다면 `reverse=True` keyword argument를 추가로 넣어준다.

# help(list.sort)을 찾아보자