# C:\> type a.txt # type은 바로 뒤에 적힌 파일 이름을 인수로 받아 해당 파일의 내용을 출력해 주는 명령어이다. 대부분의 명령 프롬프트에서 사용하는 명령어는 다음과 같이 인수를 전달하여 프로그램을 실행하는 방식을 따른다.
명령어 [인수1 인수2 ...]
# sys 모듈 사용하기 # 파이썬에서는 sys 모듈을 사용하여 프로그램에 인수를 전달할 수 있다. sys 모듈을 사용하려면 다음 예의 import sys처럼 import 명령어를 사용해야 한다.
# sys1.py import sys
args = sys.argv[1:] for i in args: print(i)
# 위는 프로그램 실행 시 전달받은 인수를 for 문을 사용해 차례대로 하나씩 출력하는 예이다. sys 모듈의 argv는 프로그램 실행 시 전달된 인수를 의미한다. 즉, 다음과 같이 입력했다면 argv[0]은 파일 이름 sys1.py가 되고 argv[1]부터는 뒤에 따라오는 인수가 차례대로 argv의 요소가 된다.
# sys2.py import sys args = sys.argv[1:] for i in args: print(i.upper(), end=' ')
# C:\doit>python sys2.py life is too short, you need python # LIFE IS TOO SHORT, YOU NEED PYTHON
# newfile2.py f = open("C:/doit/새파일.txt", 'w') f.close()
# 파일을 쓰기 모드로 열어 내용 쓰기
# write_data.py f = open("C:/doit/새파일.txt", 'w') for i in range(1, 11): data = "%d번째 줄입니다.\n" % i f.write(data) f.close()
# 위 프로그램을 다음과 비교해 보자.
for i in range(1, 11): data = "%d번째 줄입니다.\n" % i print(data)
# 두 프로그램의 다른 점은 data를 출력하는 방법이다. 첫 번째는 모니터 화면 대신 파일에 데이터를 적는 방법, 두 번째는 우리가 계속 사용해 왔던 모니터 화면에 데이터를 출력하는 방법이다. 두 방법의 차이점은 print 함수 대신 파일 객체 f의 write 함수를 사용한 것 말고는 없으므로 바로 눈에 들어올 것이다.
# 글씨가 깨지는경우 encoding을 통해 한글로 지정해줘야 함. # f = open("C:/doit/새파일.txt", 'w', encoding="UTF-8")
# 파일을 읽는 여러 가지 방법
# readline 함수 이용하기
# readline_test.py f = open("C:/doit/새파일.txt", 'r') line = f.readline() print(line) f.close()
# 위는 ‘새파일.txt’ 파일을 읽기 모드로 연 후 readline()을 사용해서 파일의 첫 번째 줄을 읽어 출력하는 예제이다. 앞에서 만든 새파일.txt 파일을 수정하거나 지우지 않았다면 위 프로그램을 실행했을 때 새파일.txt 파일의 가장 첫 번째 줄이 화면에 출력될 것이다.
# readline_all.py f = open("C:/doit/새파일.txt", 'r') while True: line = f.readline() if not line: break print(line) f.close()
# while True: 무한 루프 안에서 f.readline()을 사용해 파일을 계속 한 줄씩 읽어 들인다. 만약 더 이상 읽을 줄이 없으면 break를 수행한다(readline()은 더 이상 읽을 줄이 없을 경우, 빈 문자열('')을 리턴한다).
# 한 줄씩 읽어 출력할 때 줄 끝에 \n 문자가 있으므로 빈 줄도 같이 출력된다.
while True: data = input() if not data: break print(data)
# 위 예는 사용자의 입력을 받아 그 내용을 출력하는 경우이다. 파일을 읽어서 출력하는 예제와 비교해 보자. 입력을 받는 방식만 다르다는 것을 바로 알 수 있을 것이다. 두 번째 예는 키보드를 사용한 입력 방법, 첫 번째 예는 파일을 사용한 입력 방법이다.
# readlines 함수 사용하기
# readlines.py f = open("C:/doit/새파일.txt", 'r') lines = f.readlines() for line in lines: print(line) f.close()
# 줄 바꿈(\n) 문자 제거하기 # 파일을 읽을 때 줄 끝의 줄 바꿈(\n) 문자를 제거하고 사용해야 할 경우가 많다. 다음처럼 strip 함수를 사용하면 줄 바꿈 문자를 제거할 수 있다.
f = open("C:/doit/새파일.txt", 'r') lines = f.readlines() for line in lines: line = line.strip() # 줄 끝의 줄 바꿈 문자를 제거한다. replace('\n', '') 대체 가능 print(line) f.close()
# read 함수 사용하기
# read.py f = open("C:/doit/새파일.txt", 'r') data = f.read() print(data) f.close()
# f.read()는 파일의 내용 전체를 문자열로 리턴한다.
# 파일 객체를 for 문과 함께 사용하기
# read_for.py f = open("C:/doit/새파일.txt", 'r') for line in f: print(line) f.close()
# 파일 객체(f)는 기본적으로 위와 같이 for 문과 함께 사용하여 파일을 줄 단위로 읽을 수 있다.
# 파일에 새로운 내용 추가하기 # 쓰기 모드('w')로 파일을 열 때 이미 존재하는 파일을 열면 그 파일의 내용이 모두 사라지게 된다. 하지만 원래 있던 값을 유지하면서 단지 새로운 값만 추가해야 할 경우도 있다. 이런 경우에는 파일을 추가 모드('a')로 열면 된다. IDLE 에디터로 다음 소스 코드를 작성해 보자.
# add_data.py f = open("C:/doit/새파일.txt",'a') for i in range(11, 20): data = "%d번째 줄입니다.\n" % i f.write(data) f.close()
# 위는 새파일.txt 파일을 추가 모드('a')로 열고 write를 사용해서 결괏값을 기존 파일에 추가해 적는 예이다. 여기에서 추가 모드로 파일을 열었기 때문에 새파일.txt 파일이 원래 가지고 있던 내용 바로 다음부터 결괏값을 적기 시작한다.
# with 문과 함께 사용하기
f = open("foo.txt", 'w') f.write("Life is too short, you need python") f.close()
# 파일을 열면(open) 항상 닫아(close) 주어야 한다. 이렇게 파일을 열고 닫는 것을 자동으로 처리할 수 있다면 편리하지 않을까? 파이썬의 with 문이 바로 이런 역할을 해 준다. 다음 예는 with 문을 사용해서 위 예제를 다시 작성한 모습이다.
# file_with.py with open("foo.txt", "w") as f: f.write("Life is too short, you need python")
# 위와 같이 with 문을 사용하면 with 블록(with 문에 속해 있는 문장)을 벗어나는 순간, 열린 파일 객체 f가 자동으로 닫힌다.
# 함수란 무엇인가? # 입력값을 가지고 어떤 일을 수행한 후 그 결과물을 내어 놓는 것이 바로 함수가 하는 일이다.
# 함수를 사용하는 이유? # 반복되는 부분이 있을 경우, ‘반복적으로 사용되는 가치 있는 부분’을 한 뭉치로 묶어 ‘어떤 입력값을 주었을 때 어떤 결괏값을 리턴해 준다’라는 식의 함수로 작성하는 것이다.
# 함수를 사용하는 또 다른 이유는 자신이 작성한 프로그램을 기능 단위의 함수로 분리해 놓으면 프로그램 흐름을 일목요연하게 볼 수 있기 때문이다. 프로그램에서도 입력한 값이 여러 함수를 거치면서 원하는 결괏값을 내는 것을 볼 수 있다. 이렇게 되면 프로그램 흐름도 잘 파악할 수 있고 오류가 어디에서 나는지도 쉽게 알아차릴 수 있다.
# 파이썬 함수의 구조
def 함수_이름(매개변수): 수행할_문장1 수행할_문장2 ...
def add(a, b): return a + b
# 이 함수의 이름은 add이고 입력으로 2개의 값을 받으며 리턴값(출력값)은 2개의 입력값을 더한 값이다.
a = 3 b = 4 c = add(a, b) # add(3, 4)의 리턴값을 c에 대입 print(c) 7
# 매개변수와 인수 # 매개변수(parameter)와 인수(arguments)는 혼용해서 사용하는 용어이므로 잘 기억해 두자. 매개변수는 함수에 입력으로 전달된 값을 받는 변수, 인수는 함수를 호출할 때 전달하는 입력값을 의미한다.
def add(a, b): # a, b는 매개변수 return a+b
print(add(3, 4)) # 3, 4는 인수
# 입력값을 다른 말로 함수의 인수, 파라미터, 매개변수 등으로 말하기도 하고, 함수의 리턴값을 결괏값, 출력값, 반환값, 돌려 주는 값 등으로 말하기도 한다.
# 입력값과 리턴값에 따른 함수의 형태
# 일반적인 함수
def 함수_이름(매개변수): 수행할_문장 ... return 리턴값
def add(a, b): result = a + b return result
a = add(3, 4) print(a) 7
리턴값을_받을_변수 = 함수_이름(입력_인수1, 입력_인수2, ...)
# 입력값이 없는 함수
def say(): return 'Hi'
a = say() print(a) # Hi
# 위 함수를 쓰기 위해서는 say()처럼 괄호 안에 아무런 값도 넣지 않아야 한다. 이 함수는 입력값은 없지만, 리턴값으로 "Hi"라는 문자열을 리턴한다. 즉, a = say()처럼 작성하면 a에 "Hi"라는 문자열이 대입되는 것이다.
# a 값으로 None이 출력되었다. None이란 ‘거짓을 나타내는 자료형’이라고 언급한 적이 있다. None을 리턴한다는 것은 리턴값이 없다는 것이다.
# 입력값도, 리턴값도 없는 함수
def say(): print('Hi')
say() # Hi
# 매개변수를 지정하여 호출하기
# 함수를 호출할 때 매개변수를 지정할 수도 있다. def sub(a, b): return a - b
result = sub(a=7, b=3) # a에 7, b에 3을 전달 print(result) 4
# 매개변수를 지정하면 다음과 같이 순서에 상관없이 사용할 수 있다는 장점이 있다.
result = sub(b=5, a=3) # b에 5, a에 3을 전달 print(result) -2
# 입력값이 몇 개가 될지 모를 때는 어떻게 해야 할까?
def 함수_이름(*매개변수): 수행할_문장 ...
# 여러 개의 입력값을 받는 함수 만들기
# 다음 예를 통해 여러 개의 입력값을 모두 더하는 함수를 직접 만들어 보자. 예를 들어 add_many(1, 2)이면 3, add_many(1, 2, 3)이면 6, add_many(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)이면 55를 리턴하는 함수를 만들어 보자.
def add_many(*args): result = 0 for i in args: result = result + i # *args에 입력받은 모든 값을 더한다. return result
# 위에서 만든 add_many 함수는 입력값이 몇 개이든 상관없다. *args처럼 매개변수 이름 앞에 *을 붙이면 입력값을 전부 모아 튜플로 만들어 주기 때문이다. 만약 add_many(1, 2, 3)처럼 이 함수를 쓰면 args는 (1, 2, 3)이 되고 add_many(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)처럼 쓰면 args는 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)이 된다. 여기에서 *args는 임의로 정한 변수 이름이다. *pey, *python처럼 아무 이름이나 써도 된다.
result = add_many(1,2,3) print(result) 6 result = add_many(1,2,3,4,5,6,7,8,9,10) print(result) 55
# 여러 개의 입력을 처리할 때 def add_many(*args)처럼 함수의 매개변수로 *args 하나만 사용할 수 있는 것은 아니다. 다음 예를 살펴보자.
def add_mul(choice, *args): if choice == "add": # 매개변수 choice에 "add"를 입력받았을 때 result = 0 for i in args: result = result + i elif choice == "mul": # 매개변수 choice에 "mul"을 입력받았을 때 result = 1 for i in args: result = result * i return result
result = add_mul('add', 1,2,3,4,5) print(result) 15 result = add_mul('mul', 1,2,3,4,5) print(result) 120
# 키워드 매개변수, kwargs
# 이번에는 키워드 매개변수에 대해 알아보자. 키워드 매개변수를 사용할 때는 매개변수 앞에 별 2개(**)를 붙인다. 역시 이것도 예제로 알아보자. 먼저 다음과 같은 함수를 작성해 보자.
# 함수의 입력값으로 a=1이 사용되면 kwargs는 {'a': 1}이라는 딕셔너리가 되고 입력값으로 name='foo', age=3이 사용되면 kwargs는 {'age': 3, 'name': 'foo'}라는 딕셔너리가 된다. 즉, **kwargs처럼 매개변수 이름 앞에 **을 붙이면 매개변수 kwargs는 딕셔너리가 되고 모든 Key=Value 형태의 입력값이 그 딕셔너리에 저장된다는 것을 알 수 있다.
# 함수의 리턴값은 언제나 하나이다
def add_and_mul(a,b): return a+b, a*b
result = add_and_mul(3,4)
# 리턴값은 a+b와 a*b인데, 리턴값을 받아들이는 변수는 result 하나만 쓰였으므로 오류가 발생하지 않을까? 당연한 의문이다. 하지만 오류는 발생하지 않는다. 그 이유는 함수의 리턴값은 2개가 아니라 언제나 1개라는 데 있다. add_and_mul 함수의 리턴값 a+b와 a*b는 튜플값 하나인 (a+b, a*b)로 리턴된다.
result = (7, 12)
# 만약 이 하나의 튜플 값을 2개의 값으로 분리하여 받고 싶다면 함수를 다음과 같이 호출하면 된다.
# add_and_mul(2, 3)의 리턴값은 5 하나뿐이다. 두 번째 return 문인 return a * b는 실행되지 않았다는 뜻이다. 즉, 함수는 return 문을 만나는 순간, 리턴값을 돌려 준 다음 함수를 빠져나가게 된다.
# 이 함수는 다음과 완전히 동일하다. def add_and_mul(a,b): return a+b
# 즉 함수는 return문을 만나는 순간 결괏값을 돌려준 다음 함수를 빠져나가게 된다.
# return의 또 다른 쓰임새
def say_nick(nick): if nick == "바보": return print("나의 별명은 %s 입니다." % nick) # 위는 매개변수 nick으로 별명을 입력받아 출력하는 함수이다. 이 함수 역시 리턴값은 없다. 이때 문자열을 출력한다는 것과 리턴값이 있다는 것은 전혀 다른 말이므로 혼동하지 말자. 함수의 리턴값은 오로지 return 문에 의해서만 생성된다.
# 만약 입력값으로 '바보'라는 값이 들어오면 문자열을 출력하지 않고 함수를 즉시 빠져나간다.
# 바뀐 부분은 초깃값을 설정한 매개변수의 위치 # 초기화하고 싶은 매개변수는 항상 뒤쪽에 놓아야 한다는 것을 잊지 말자.
# 함수 안에서 선언한 변수의 효력 범위
# vartest.py a = 1 # 전역변수 def vartest(a): a = a +1 # 지역변수
vartest(a) print(a)
# 함수 안에서 사용하는 매개변수는 함수 안에서만 사용하는 ‘함수만의 변수’이기 때문이다. 즉, def vartest(a)에서 입력값을 전달받는 매개변수 a는 함수 안에서만 사용하는 변수일 뿐, 함수 밖의 변수 a와는 전혀 상관없다는 뜻이다.
# vartest_error.py def vartest(a): a = a + 1
vartest(3) print(a)
# 함수 안에서 선언한 매개변수는 함수 안에서만 사용될 뿐, 함수 밖에서는 사용되지 않는다.
# 함수 안에서 함수 밖의 변수를 변경하는 방법
# 1. return 사용하기
# vartest_return.py a = 1 def vartest(a): a = a +1 return a
a = vartest(a) print(a)
# 첫 번째 방법은 return을 사용하는 방법이다. vartest 함수는 입력으로 들어온 값에 1을 더한 값을 리턴하도록 변경했다. 따라서 a = vartest(a)라고 작성하면 a에는 vartest 함수의 리턴값이 대입된다.
# 여기에서도 물론 vartest 함수 안의 a 매개변수는 함수 밖의 a와는 다른 것이다.
# 2. global 명령어 사용하기
# vartest_global.py a = 1 def vartest(): global a a = a+1
vartest() print(a)
# 두 번째 방법은 global 명령어를 사용하는 방법이다. 위 예에서 볼 수 있듯이 vartest 함수 안의 global a 문장은 함수 안에서 함수 밖의 a 변수를 직접 사용하겠다는 뜻이다. 하지만 프로그래밍을 할 때 global 명령어는 사용하지 않는 것이 좋다. 함수는 독립적으로 존재하는 것이 좋기 때문이다. 외부 변수에 종속적인 함수는 그다지 좋은 함수가 아니다. 따라서 되도록 global 명령어를 사용하는 이 방법은 피하고 첫 번째 방법을 사용하기를 권한다.
a = [1,2,3,4] print(a.append(5)) None # def append(num): # # 리스트에 하나를 추가함 # return None
a = [1,2,3,4] result = a.append(5) print(result) None print(a) [1,2,3,4,5]
a = [1,2,3,4] result = a.insert(0,10) print(result) None print(a) [10,1,2,3,4]
a = [1,2,3,4] result = a.pop() # return 값이 있음. return 4 print(result) 4 print(a) [1,2,3]
# lambda 예약어 # lambda는 함수를 생성할 때 사용하는 예약어로, def와 동일한 역할을 한다. 보통 함수를 한 줄로 간결하게 만들 때 사용한다. 우리말로는 ‘람다’라고 읽고 def를 사용해야 할 정도로 복잡하지 않거나 def를 사용할 수 없는 곳에 주로 쓰인다.
함수_이름 = lambda 매개변수1, 매개변수2, ... : 매개변수를_이용한_표현식
add = lambda a, b: a+b result = add(3, 4) print(result) 7
# lambda로 만든 함수는 return 명령어가 없어도 표현식의 결괏값을 리턴한다.
# add는 2개의 인수를 받아 서로 더한 값을 리턴하는 lambda 함수이다. 위 예제는 def를 사용한 다음 함수와 하는 일이 완전히 동일하다.
def add(a, b): return a+b
result = add(3, 4) print(result) 7
a = [lambda a, b: a+b, lambda a, b: a*b] print(a[0](3,4)) 7 print(a[1](3,4)) 12
# 조건문의 참과 거짓 # 1. 다음 코드의 결괏값은 무엇일까? a = "Life is too short, you need python"
if "wife" in a: print("wife") elif "python" in a and "you" not in a: print("python") elif "shirt" not in a: print("shirt") elif "need" in a: print("need") else: print("none")
# shirt
# 가장 먼저 참이 되는 것
# 3의 배수의 합 구하기 # 2. while문을 사용해 1부터 1000까지의 자연수 중 3의 배수의 합을 구해 보자. result = 0 i = 1 while i <= 1000: if i % 3 == 0: result += i i += 1 print(result)
# 별 표시하기 # 3. while 문을 사용하여 다음과 같이 별(*)을 표시하는 프로그램을 작성해 보자.
i = 0 while True: i += 1 if i > 5 : break print ( i * " * " ) --> ' * ' * i
# 1 부터 100까지 출력하기 # 4. for문을 사용해 1부터 100까지의 숫자를 출력해 보자. for i in (range(1,101)): print(i)
# 평균 점수 구하기 # 5. A학급에 총 10명의 학생이 있다. 이 학생들의 중간고사 점수는 다음과 같다. # [70, 60, 55, 75, 95, 90, 80, 80, 85, 100] # for문을 사용하여 A 학급의 평균 점수를 구해 보자.
A = [70, 60, 55, 75, 95, 90, 80, 80, 85, 100] total = 0 for score in A: total += score average = total / 10 --> total / len(A) print(average)
# 리스트 컴프리헨션 사용하기 # 6. 다음 소스 코드는 리스트의 요소 중에서 홀수만 골라 2를 곱한 값을 result 리스트에 담는 예제이다.
numbers = [1, 2, 3, 4, 5] result = [] for n in numbers: if n % 2 == 1: result.append( n * 2 ) # 이 코드를 리스트 컴프리헨션을 사용하여 표현해 보자.
numbers = [1, 2, 3, 4, 5] result = [n*2 for n in numbers if n % 2 == 1] print(result)