딕셔너리를 사용하다보면 key와 value를 서로 바꾼 형태의 새로운 딕셔너리를 만들 일이 생긴다.

key와 value를 도치시키는 코드를 직접 짜보면

a={'a':1,'b':2,'c':3,'d':1}; #도치 대상

b={}; #도치 후 저장할 딕셔너리
for key, value in a.items():
    if value in b:
        b[value].append(key);	#이미 (value)를 키로 하는 값 (key)가 존재	->괄호안의 값은 변수
    else:
        b[value]=[key];			#해당 value,key값이 존재하지 않으면

print(b);

>>{1: ['a', 'd'], 2: ['b'], 3: ['c']}

위와 같이 할 수 있겠지만 더 간단한 방법으로는 컬렉션 내포(Comprehension)를 사용하는 것이다.

컬렉션 내포란 지정된 표현식을 사용해 좀 더 간단히(?) 컬렉션을 생성하는 방법이다.

리스트, 딕셔너리, 셋 모두 가능하지만 이 글에서는 딕셔너리에 대한 예시를 보겠다.

 

a={'a':1,'b':2,'c':3,'d':1}; #도치 대상
b={value:key for key,value in a.items()}	#딕셔너리 컬렉션 내포 표현식
print(b);

>>{1: 'd', 2: 'b', 3: 'c'}

 위와 같이 좀 더 간단하게 표현이 가능하다.

하지만 뭔가 이상한 것을 볼 수 있다. 우리 생각대로라면 위처럼 1:['a','d']가 나와야겠지만 컬렉션 내포 방식으로는 하나의 key당 하나의 value만 저장이 가능하다.

따라서 동일한 value가 없는 것을 한눈에 알아볼 수 있는 딕셔너리라면 컬렉션 내포 방식을 사용하는 것이 편하겠지만 대부분의 딕셔너리는 맨 위의 예시와 같이 도치시키는 것이 좋다.

'Python' 카테고리의 다른 글

Python - 클래스(Class)와 객체(Object)  (0) 2020.08.09
Python - 컬렉션 정리  (0) 2020.08.04
Python - with 문  (0) 2020.08.01
Python - is와 ==의 차이 (and,or,&,|)  (1) 2020.07.29
Python - 에일리어스(alias)  (0) 2020.07.29

Python도 다른 프로그래밍 언어와 똑같이 파일을 읽고, 쓰는 작업을 지원한다.

file = open('test.txt','r')		#파일 열기	'r'은 파일을 읽겠다는 뜻.(read)
contents = file.read()			#파일을 읽어서 contents변수에 저장
file.close()					#파일 닫기
print(contents)


>>I like Python

#test.txt

I like Python


파일을 읽고 쓰는 법은 위와 같다.

파일을 열었으면 작업을 끝낸 후 꼭 닫아주어야 하는데, 위의 방식을 사용한 채로 작업을 진행하다 문제가 생기면 

file.close() 문을 실행할 수 없게 된다. 해당 문장을 생략해도 프로그램을 종료할 때 파이썬이 열려 있는 파일의 객체를 자동으로 닫아주기는 하지만, close()를 사용해 열려 있는 파일을 직접 닫아주는 것이 좋다. 쓰기모드로 열었던 파일을 닫지 않고 다시 사용하려고 하면 오류가 발생하기 때문이다.

파이썬은 이와 같은 상황에 대비해 오류가 발생하든 안 하든 항상 파일을 깔끔하게 정리할 수 있게 with 문을 제공한다.

#with문 형식

with <<expression>> as <<variable>> :

     작업 코드....



사용 예시

with open('test.txt','r') as file:
	contents = file.read()
    
print(contents)

x=file.read()		#with문 밖에서 file을 읽으려고함. 오류발생. (파일이 잘 닫혔다는 뜻)
print(x)

>>I like Python
Traceback (most recent call last):
  File "...................................", line 6, in <module>
    x=file.read();
ValueError: I/O operation on closed file.

Process finished with exit code 1

with문을 사용하면 close문을 쓰지 않아도 파일이 잘 닫히는 것을 볼 수 있다.

특수한 경우가 아니라면 with문을 사용하자.

어떠한 이유가 있어 with문을 사용하지 않는다면 잊지말고 close()문으로 파일을 잘 닫아주도록하자.

 

 

출처 : 파이썬 프로그래밍 교과서(개정 3판)

'Python' 카테고리의 다른 글

Python - 컬렉션 정리  (0) 2020.08.04
Python - 딕셔너리 키(key), 값(value) 도치  (0) 2020.08.04
Python - is와 ==의 차이 (and,or,&,|)  (1) 2020.07.29
Python - 에일리어스(alias)  (0) 2020.07.29
Python - 모듈(module)  (0) 2020.07.27

is


   -식별 연산자(identity operator)로서 값이 아닌 주소를 비교한다.

 

==


   -비교 연산자로서 값을 비교한다.

 

 

 

예시

n1 = 257
n2 = 257

s1 = "duck"
s2 = "duck"

print(n1 == n2)
print(n1 is n2)

print(s1 == s2)
print(s1 is s2)

>>True
>>True
>>True
>>True
n1 = 257
n2 = 256

s1 = "duck"
s2 = "duc"

print(n1 == n2+1)
print(n1 is n2+1)

print(s1 == (s2+'k'))
print(s1 is (s2+'k'))

>>True
>>False
>>True
>>False

 

위의 예시는 모두 True가 나온 것을 볼 수 있고 

아래의 예시는 is 연산에서 False가 나온 것을 볼 수 있다.

 

파이썬은 새로운 변수에 할당하려는 값이 이미 메모리에 존재하면 새로운 값을 생성하지 않고

기존에 존재하는 메모리를 가리키게 한다.

 

아래의 예시를 보면

연산의 값은 257, duck 둘 다 동일하나 n1과 n2(s1과 s2)가 가리키는 메모리 주소가 다르기 때문에 is연산에서는 False가 반환되는 것을 볼 수 있다.

 

n1 = 257
n2 = 256

s1 = "duck"
s2 = "duc"

print(id(n1))
print(id(n2+1))

print(id(s1))
print(id(s2+'k'))

>>1356657452880
>>1356657452464
>>1356657710840
>>1356686985848

#메모리 주소값이 다른 것을 확인할 수 있다.

 

※예시와 다르게 257보다 작은 양의 정수를 사용하면 is연산을 해도 True값이 나오는 것을 볼 수 있다. 

  Python은 자주 사용되는 작은 정수, [-5,256] 범위의 정수들을 미리 캐싱해놓기 때문에 해당 범위의 값은 항상 같은 주    소를 가리킨다.

'Python' 카테고리의 다른 글

Python - 딕셔너리 키(key), 값(value) 도치  (0) 2020.08.04
Python - with 문  (0) 2020.08.01
Python - 에일리어스(alias)  (0) 2020.07.29
Python - 모듈(module)  (0) 2020.07.27
Python - 단락 평가(Short-circuit Evaluation)  (0) 2020.07.26

파이썬에서 두 변수가 가리키는 메모리 주소가 같으면 서로의 에일리어스(alias)라고 말한다.

문자열처럼 그 자체의 값이 변경 불가능한 값은 에일리어스를 생성해도 안전하지만,

리스트(list) 같은 가변적인 값은 에일리어스를 생성하게 되면 프로그램의 흐름이 개발자의 의도와 다르게 흘러갈 수 있다.

 

예시

list1 = [1,2,3,4,5]
list2 = list1		#list1과 list2는 alias
list1[0]=0			#list1[0]값 변경
print(list1)
print(list2)

>>[0, 2, 3, 4, 5]
>>[0, 2, 3, 4, 5]	#list2[0]값도 변경된 것을 볼 수 있다.

list1과 list2는 같은 리스트를 참조하고 있고, 인덱싱을 이용해 새로운 리스트를 생성하는 것이 아니라 list1[0]의 값을 "변경"하게 되므로 이와 같은 결과가 나타난다. (두 리스트가 함께 참조하고 있는 리스트의 값을 변경)

 


한 리스트와 그 리스트를 인수로 받은 매개변수도 서로 에일리어스 관계이다.

def remove_list(L:list) ->None:
    del L[0]		#매개변수 L의 값을 변경	(L과 아래의 list1은 같은 리스트를 참조)
list1 = [1,2,3,4,5]
remove_list(list1)		#L == list1
print(list1)

>>[2,3,4,5]

list1의 값을 복사해서 L에게 전달해주는 것으로 보일 수 있으나 실제로는 list1이 가리키는 주소 값을 전달해 주는 것이다.

'Python' 카테고리의 다른 글

Python - with 문  (0) 2020.08.01
Python - is와 ==의 차이 (and,or,&,|)  (1) 2020.07.29
Python - 모듈(module)  (0) 2020.07.27
Python - 단락 평가(Short-circuit Evaluation)  (0) 2020.07.26
Python - 사용자 입력(input())  (0) 2020.07.26

모듈이란 한 파일로 묶인 변수와 함수의 모음이다.

프로그램을 작성할 때 한 파일 안에 모든 변수와 함수를 저장하는 것보다, 여러 모듈을 생성해 용도가 비슷한 변수와 함수끼리 묶어 작성하는 것이 좋다.

 

모듈 사용법


모듈을 작성하는 법은 간단하다. main으로 사용할 파이썬 파일과 같은 디렉토리에 새로운 파이썬 파일을 생성한 뒤

필요한 함수와 변수를 작성하면 된다.

작성한 모듈을 사용하는 법은

먼저 모듈을 작성한 뒤

#test.py		#test모듈 생성

x=1
y=2

def add(a:int,b:int)->int:
	return a+b;
    

해당 모듈을 사용할 파일에서 import한 후 변수 또는 함수를 사용하면 된다.

import test			#test모듈을 import한다.

x = test.x+test.y
result = test.add(x,5);	
print(result)

>>8

 

 

위의 예제를 보면 추가한 모듈의 변수와 함수를 사용할 때는 꼭 앞에 <<모듈명>>. 을 붙여준다.

모듈명을 붙이지 않고 사용하면

import test

result=add(3,5)

print(result)

>>Traceback (most recent call last):
  File ".................................", line 3, in <module>
    result=add(3,5);
NameError: name 'add' is not defined	#함수 add를 찾을 수 없다는 오류

 

파이썬에서 모듈을 import 하게 되면 모듈과 같은 이름의 변수가 형성된다.

import test

print(type(test))

>> <class 'module'>	#타입은 module

test파일에서 작성한 변수와 함수는 위의 변수 test 내부에 저장되어있다.

import test

print(help(test))

>>Help on module test:

NAME
    test

FUNCTIONS
    add(a: int, b: int) -> int

DATA
    x = 1
    y = 2

FILE
    c:...........................\test.py		#파일 경로


None

따라서 모듈 내부의 변수나 함수를 사용할 때는 꼭 모듈명을 붙여줘야 한다.

 

 


※모듈의 변수나 함수중 일부분만 import하는 방법도 있다.

from test import add		#from <<모듈명>> import <<변수명,함수명>>

print(add(3,5))		#test모듈의 add만 가져온 것이므로 앞에 모듈명을 붙이지않아도 된다.

>>8

단락 평가(Short-circuit Evaluation)


파이썬은 and나 or를 포함하는 식을 평가할 때 왼쪽에서 오른쪽으로 평가한다.

이때 평가를 멈출만한 충분한 정보를 얻으면 아직 평가하지 않는 피연산자가 있어도 바로 멈춘다.

※ or표현식에서 첫 번째 피연산자가 True이면 다음 피연산자를 보지않아도 값이 True인 것을 알 수 있다.

※ and표현식에서 첫 번째 피연산자가 False이면 다음 피연산자를 보지않아도 값이 False인 것을 알 수 있다.

예시


오류를 일으키는 식

print(1/0)

>>Traceback (most recent call last):			#ZeroDivisionError 발생
  File "....................................", line 1, in <module>
    print(1/0);
ZeroDivisionError: division by zero

 

위의 식을 or의 두 번째 피연산자로 사용하면

print((2<3)or(1/0))

>>True		#두 번째 피연산자에서 오류가 발생해야하지만 그렇지않고 True가 출력

첫 번째 피연산자가 True이기때문에 두 번째 피연산자를 확인하지않고 오류도 출력하지않는다.

 

 

※결과값이 잘 출력된다고해도 프로그램 내부에 오류가 존재할 수 있음을 기억하자.

 

 

 

출처:파이썬 프로그래밍 교과서 개정3판

'Python' 카테고리의 다른 글

Python - 에일리어스(alias)  (0) 2020.07.29
Python - 모듈(module)  (0) 2020.07.27
Python - 사용자 입력(input())  (0) 2020.07.26
Python - 부동소수점(Floating Point), 유한 정밀도  (0) 2020.07.24
Python - 문자열 변경  (0) 2020.07.23

입력


파이썬에서는 input()함수로 사용자 입력을 받을 수 있다.

name=input()
print(name)

>>>duck #사용자가 직접 입력
>>>duck #출력

 

input() 함수는 모든 입력을 문자열로 취급한다. 따라서 int, float형을 입력할 때는 형변환이 필요하다.

age=input()	#형변환을 해주지 않았기 때문에 입력을 문자열로 인식
print(age+5)

>>>24 #입력
>>>Traceback (most recent call last):				#출력 ->오류 발생
  File ".....................................", line 2, in <module>
    print(age+5);
TypeError: can only concatenate str (not "int") to str		#TypeError 발생

 

age=int(input())	#형변환
print(age+5)

>>>24		#입력
>>>29		#출력	-> age가 int형이므로 숫자 5와 연산 가능.

input()함수로 프롬프트 출력도 가능하다.

name=input("이름을 입력해주세요: ")	#input함수의 인자로 문자열 입력
print(name)

>>>이름을 입력해주세요: 오리
>>>오리

'Python' 카테고리의 다른 글

Python - 모듈(module)  (0) 2020.07.27
Python - 단락 평가(Short-circuit Evaluation)  (0) 2020.07.26
Python - 부동소수점(Floating Point), 유한 정밀도  (0) 2020.07.24
Python - 문자열 변경  (0) 2020.07.23
python- 문자열 포매팅  (0) 2020.07.23

부동소수점이란


부동소수점을 설명하기 앞서 고정소수점에 대해 간단히 설명하겠다.

고정소수점이란 각각 정수와 소수를 표현하는 비트의 수를 미리 정해 놓고 정해진 비트 만큼만 사용해서 수를 표현하는 방식이다.

 

부동소수점이란 컴퓨터가 실수를 표현할 때 사용하는 방법 중 하나로, 고정소수점 방식과는 다르게 소수점의 위치를 고정하지 않고 소수점의 위치를 나타내는 수를 따로 적어 표현한다.

※유효숫자를 나타내는 가수와 소수점의 위치를 나타내는 지수로 부동 소수점을 표현한다.

 

예를 들어 123.4 를 고정소수점, 부동소수점으로 나타내보면

고정소수점으로 표현 하면 123.4 한 가지 표현만 가능.

부동소수점 방식의 지수와 가수를 이용하면 [1.234 * 10^2], [12.34 *10^1] 등 여러 방식으로 표현이 가능하다.


유한 정밀도


파이썬에서 나타내는 부동소수점 수는 값이 길어질수록 부정확해진다.

 

예를 들어 파이썬에서 각각 2/3 연산과 5/3 연산을 해보면

print(2/3)
print(5/3)

>>0.6666666666666666
>>1.6666666666666667

위와 같이 출력된다.

사람이 하는 연산이라면 두 값 모두 끝자리가 6으로 반복되겠지만 파이썬은 그렇지않다.

이러한 현상이 발생하는 이유는 컴퓨터 메모리 용량이 한정되어 있고 파이썬이 한 숫자에 대해 저장하는 정보 용량을 제한하기 때문이다.

따라서 위의 값들은 제한된 양의 메모리에 실제로 저장할 수 있는 각 연산(2/3), (5/3)의 답에 가장 가까운 값이다.

 

사람이 생각하기에 2/3과 0.6666666666666666의 차이는 작아보일 수 있지만 실제 계산에서 0.6666666666666666를 사용할 떄 일어날 오류는 심각하다.

5/3은 1+(2/3)과 같은 값이지만 파이썬으로 계산을 해보면

print(1+(2/3))
print(5/3)

>>1.6666666666666665
>>1.6666666666666667

위와 같이 서로 다른 값이 나온다.

※계산을 더 할수록 오류는 더 커지고, 특히 매우 큰 수와 매우 작은 수를 연산하면 더 커진다.


부동소수점이 갖는 이러한 문제를 항상 인지하고 있어야 한다.

컴퓨터는 위에서 말한 것처럼 메모리에 한계가 있기 때문에 이 문제를 완벽히 해결할 방법은 없다.

부동소수점간의 연산에서는 최대한 작은 수부터 계산하는 것이 오류를 최소화하는 유일한 방법이다.

 

파이썬에서 문자열(string)은 인덱싱은 가능하나, 리스트와는 다르게 인덱스를 이용한 값 변경은 불가능하다.

따라서 지정된 함수를 이용해서 문자열을 변경해야 한다.

 

 문자열 변경 - replace('old','new')


a = 'I love Java'
a=a.replace('Java','Python')
print(a)

>>I love Python

 

 

문자열 내 문자 변경 - str.maketrans('old','new'), translate(table)


문자 변경은 문자열 변경과 다르게 두 가지 과정이 필요하다.

먼저 str.maketrans()를 이용하여 바꿀 문자와 새로운 문자 간의 변환 테이블을 만들어야 한다.(1대 1 대응)

그 후 문자를 변경하고 싶은 문자열을 대상으로 translate 함수를 사용하면 된다.

말이 어려운데 예시를 보자.

a = 'my name is duck'
table = str.maketrans('abcdefghi','123456789') #1대1대응
a = a.translate(table)
print(a)

>>my n1m5 9s 4u3k

위의 예시의 table을 출력해보면

table = str.maketrans('abcdefghi','123456789')
print(table)

>>{97: 49, 98: 50, 99: 51, 100: 52, 101: 53, 102: 54, 103: 55, 104: 56, 105: 57}

위와 같이 a:1, b:2, c:3 ... 가 아스키코드로 변환되어 딕셔너리 형태로 저장되어 있는 것을 볼 수 있다.

이 테이블을 이용하여 translate함수를 사용하면 

'my name is duck'이 'my n1m5 9s 4u3k'으로 변환되는 것을 볼 수 있다.

 

 

※str.maketrans()함수를 사용할 때는 꼭 두 인자의 길이가 같아야 한다!!!(위에서 말한 1대 1 대응)

문자열 포매팅이란 문자열 안에 어떤 값을 삽입하는 방법이다. (c언어를 해보았다면 printf를 떠올리면 좋을 듯.)

포매팅의 방법에는 %d,%s와 같은 포맷 코드를 사용하는 방법과 format 함수를 사용하는 방법 등이 있다.

age = 24

print("I am %d years old" %age)	#포맷 코드 사용(코드 종류는 아래에서 설명)
print("I am {0} years old".format(age))	#format 함수 사용
print("I am {0} {1} old".format(age,'years'))	# ,로 구분하여 여러개도 입력 가능
print("I am {a} years old".format(a=24))	#이름을 정해서 넣을 수도 있다.

>>I am 24 years old
>>I am 24 years old
>>I am 24 years old
>>I am 24 years old

※포맷 코드

코드 설명
%s 문자열(string)
%c 문자 1개(character)
%d 정수(integer)
%f 부동소수(float)
%o 8진수
%x 16진수
%% 문자 %

 

 

리스트를 이용한 포매팅도 가능하다.

x=[1,2,3]
print("{p[0]} and {p[1]} and {p[2]}".format(p=x))

>>1 and 2 and 3

 

 


f 문자열 포매팅


파이썬 3.6 버전부터는 f 문자열 포매팅이란 걸 사용할 수 있다.

 

아래와 같이 먼저 문자열 변수를 선언하고 출력 또는 복사할 문자열 앞에 f를 붙이면 사용이 가능하다.

name = 'duck'
age = 24
print(f"My name is {name}.")
print(f"I am {age} years old.")

>>My name is duck.
>>I am 24 years old.

 

 

+ Recent posts