파이썬 자료형 #2

반영환·2023년 4월 29일

파이썬

목록 보기
2/17
post-thumbnail

파이썬 자료형

1. 숫자의 연산 (a.k.a 사칙연산!)

print(3 + 2) # 5
print(3 - 1) # 2
print(3 * 2) # 6

print(14 % 3) # 2
print(2 ** 4) # 16

print(12 / 4) # 3.0

#floor division(버림 나눗셈)
print(7//2) # 3
print(7.0//2) # 3.0

+ - * : edge case 존재 X

Division

  • % : 나눗셈의 나머지를 구한다.
  • / : 일반적인 나눗셈 (결과값은 항상 실수형!!)
  • // : 나눗셈의 몫을 구한다. (계산 항에 실수형이 있으면 실수형으로 리턴)

2. 반올림 문제

파이썬 내장함수인 round 함수 를 이용

print(round(3.1415926535)) # 3

#소숫점 반올림 자리를 지정하고 싶을 때
print(round(3.1415926535, 4)) # 3.1416


###round function issue###
round(4.5) # 4
round(5.5) # 6

컴퓨터는 이진수 기반으로 작동하기 때문에 소숫점을 표현함에 있어서 근사값을 사용할 수 밖에 없다.

따라서 round함수가 우리가 생각한 대로 작동하지 않을 수도 있다.

반올림 할 자리의 숫자가 5인 경우!
python3 부터는 round to nearest even 방식을 사용하기 때문에 위의 코드블럭과 같은 결과값이 나오게 된다.


3. 부동소수점의 표현 방식

컴퓨터에서 부동소수점 숫자들은 2진 분수로 표현되기에 꽤 많은 값은 정확히 표현될 수 없다.

그렇기에 사람이 이해하기 쉽게 입력하는 10진 부동소수점 숫자는 2진 부동소수점 숫자로 근사 된다.

예를 들어 10진수 0.1은 2진 분수로 정확하게 표현될 수 없고 0.0001100110011001100110...처럼 무한히 반복되기에 특정 비트에서 멈추고 근사값을 얻는다.

0.1 >>> 0.1000000000000000055511151231257827021181583404541015625

0.1에 대해 실제 십진수 값을 출력한다면 위와 같겠지만 파이썬에선 반올림된 값을 표시한다.

1 / 10 >>> 0.1

해결책

decimal.Decimal, round 함수를 이용해 해결할 수 있다.

decimal

import decimal

print((decimal.Decimal('0.1') * 3) == decimal.Decimal('0.3')) # True

print((decimal.Decimal('0.3') + 2) ==decimal.Decimal('2.3')) # True

#사용에 주의하세요!
print((decimal.Decimal(0.1 * 3)) == decimal.Decimal('0.3')) # False​

위와 같이 사전에 연산 후 Decimal함수에 파라미터로 넘기는 행위는 위험하다.

Decimal(0.1 * 3) == Decimal('0.3000000000000000444089209850062616169452667236328125')

round

print(round(0.1 + 0.1 + 0.1, 10) == round(0.3,10)) # True

print((0.1 + 0.1 + 0.1) == 0.3) # False

#decimal.Decimal(0.1 + 0.1 + 0.1) == Decimal('0.3000000000000000444089209850062616169452667236328125')
#decimal.Decimal(0.3) == Decimal('0.299999999999999988897769753748434595763683319091796875')​

#사용에 주의하세요!

print(round(0.1, 1) + round(0.1, 1) + round(0.1, 1) == round(0.3, 1)) # False

위와 같이 사전 round()는 도움이 되지 않는다. round(0.1,1) == 0.1 이기 때문에 하나 마나이다!

반올림 모드

파이썬에선 여러 가지 반올림 모드 옵션을 제공한다.
기본적으로 설정된 모드 상으론 값에 따라 어떤건 0.5더라도 내림이 되기도 하고 올림이 되기도 한다.

print(round(0.125, 2)) # 0.12
print(round(0.135, 2)) # 0.14​

반올림 모드엔 여러 가지가 있는데 기본적으로 ROUND_HALF_EVEN이라는 모드로 지정되어 있고 이는 짝수랑 가까워지는 방향으로 동작한다.

현재 적용된 반올림 방식이 무엇인지는 deciaml.getcontext()로 확인해 볼 수 있다.

import decimal

print(decimal.getcontext())

# > Context(prec=28, rounding=ROUND_HALF_EVEN, Emin = -999999, capitals=1, clamp=0, flags=[], traps =[InvalidOperation, DivisionByZero, overflow])

반올림 방식을 바꾸고 싶다면 아래 8가지 방식 중 decimal 함수를 이용해 변경이 가능하다.

ROUND_CEILING
ROUND_DOWN
ROUND_FLOOR
ROUND_HALF_DOWN
ROUND_HALF_UP
ROUND_UP
ROUND_05UP

import decimal
ctx = decimal.getcontext()
ctx.rounding = decimal.ROUND_UP

*출처 : https://blog.winterjung.dev/2020/01/06/floating-point-in-python

4. 문자열 연산

+는 문자열에선 문자열을 합쳐주는 역할을 한다.

"A" + "B" => "AB"

"A" * 3 = "AAA" # 곱셈도 가능

문자열 사용시 "와 '

"" 내부 : " 사용 불가! -> 사용시 (escape)문자 사용

'' 내부 : ' 사용 불가! -> 사용시 (escape)문자 사용

""" : """

  # 줄 바꿈이 컨텐츠에 그대로 영향을 줌

  """

5. 형변환(Type conversion / casting)

int() float() str() bool()

print(int(3.8)) # 3
print(str(3)) # "3"
print(float(3)) # 3.0

6. 문자열 포맷팅

포매팅을 하는 이유

#오늘은 2019년 10월 29일입니다.

year = 2019
month = 10
day = 29

print("오늘은 "+ str(year) + ....
#번거롭지?
# format 함수 사용

format 함수의 파라미터들은 모두 문자형으로 형 변환 됨.

# 목표 
print("오늘은 2019년 10월 29일입니다.")

# 순서대로 {}안에 넣어준다
print("오늘은 {}년 {}월 {}일입니다.".format(year, month, day))

# 더 간결한 방법!
date_string = "오늘은 {}년 {}월 {}일입니다."
print(date_string.format(year, month, day))

# 파라미터 순서 지정
print("오늘은 {1}년 {0}월 {2}일입니다.".format(year, month, day))
##오늘은 10년 2019월 29일입니다.

숫자 포맷팅시 반올림 하는 법은 {} 대신에 {:(반올림자리수)(타입(주로 f))} 를 넣으면 된다.
print("{0} 나누기 {1}은 {2:.2f}입니다".format....
:.2f => f : 소수 .2 : 소숫점 둘째자리까지 표현

정수로 바꾸고 싶을 때 :.0f

다른 포매팅 방법

가장 오래된 방식 (% 기호)

name = "반영환"
age = 23

print("제 이름은 %s이고 %d살입니다." % (name, age))

%s, %d와 같은 '포맷 스트링'이라는 것을 사용하는데, C나 자바 등 많은 언어들에서 이와 유사한 방식으로 문자열 포맷팅을 한다. 잘 안씀!

새로 나온 방식(f-string)

name = "반영환"
age = 23

print(f"제 이름은 {name}이고 {age}살입니다.")
파이썬 버전 3.6부터 새롭게 나온 방식
cf) const textcontents = `${name}${age}살 입니다.`

7. Boolean Type

불 대수 연산은 일반 사칙연산을 사용하지 않는다.

  • and : 좌우 변 모두 참일시 True

  • or : 좌우 변 하나만 참이여도 True

  • not : ~

print(True and True) # True
print(False or True) # True
print(not False) # True

# 대수연산자 : <, > , >=, <=, ==, !=

8. Type 함수

type 함수는 사용하는 값 혹은 입력받은 값의 자료형을 알려준다.

분기문을 사용해서 입력에 따른 다른 행동을 보여주어야 할 때 주로 사용한다고 함!

Anti pattern

print(type(print(3 > 1))) # <class 'NoneType'>


# 실행 순서
# print(type(print(True)))
# print(type(None))
# print(NoneType)

2021-09-05

profile
최고의 오늘을 꿈꾸는 개발자

0개의 댓글