Do it! 점프 투 파이썬 Python 자료형(4)

PM/iOS Developer KimKU·2021년 7월 31일
0
post-thumbnail

파이썬 프로그래밍의 기초, 자료형

6. 집합 자료형

6.1) 집합 자료형은 어떻게 만들까?

집합(set)은 파이썬 2.3부터 지원하기 시작한 자료형으로, 집합에 관련된 것을 쉽게 처리하기 위해 만든 자료형이다.

집합 자료형은 다음과 같이 set 키워드를 사용해 만들 수 있다.

s1 = set([1, 2, 3])

print(s1)
>>> {1, 2, 3}

위와 같이 set()의 괄호 안에 리스트를 입력하여 만들거나 다음과 같이 문자열을 입력하여 만들 수도 있다.

s2 = set("hello")

print(s2)
>>> {'e', 'h', 'l', 'o'}

6.2) 집합 자료형의 특징

자, 그런데 위에서 살펴본 set("Hello")의 결과가 좀 이상하지 않은가? 분명 "Hello" 문자열로 set 자료형을 만들었는데 생성된 자료형에는 l 문자가 하나 빠져 있고 순서도 뒤죽박죽이다. 그 이유는 set에 다음과 같은 2가지 큰 특징이 있기 때문이다.

  • 중복을 허용하지 않는다.
  • 순서가 없다(Unordered).

리스트나 튜플은 순서가 있기(ordered) 때문에 인덱싱을 통해 자료형의 값을 얻을 수 있지만 set 자료형은 순서가 없기(unordered) 때문에 인덱싱으로 값을 얻을 수 없다. 딕셔너리 역시 순서가 없는 자료형이라 인덱싱을 지원하지 않는다.

만약 set 자료형에 저장된 값을 인덱싱으로 접근하려면 다음과 같이 리스트나 튜플로 변환한 후 해야 한다.

s1 = set([1, 2, 3])
l1 = list(s1)

print(l1)
>>> [1, 2, 3]
print(l1[0]
>>> 1

t1 = tuple(s1)

print(t1)
>>> (1, 2, 3)
print(t1[0])
>>> 1

6.3) 교집합, 합집합, 차집합 구하기

set 자료형을 정말 유용하게 사용하는 경우는 교집합, 합집합, 차집합을 구할 때이다.

우선 다음과 같이 2개의 set 자료형을 만든 후 따라 해 보자. s1은 1 부터 6 까지의 값을 가지게 되었고, s2는 4부터 9까지의 값을 가지게 되었다.

s1 = set([1, 2, 3, 4, 5, 6])
s2 = set([4, 5, 6, 7, 8, 9])

교집합

s1과 s2의 교집합을 구해 보자.

s1 = set([1, 2, 3, 4, 5, 6])
s2 = set([4, 5, 6, 7, 8, 9])

print(s1 & s2)
>>> {4, 5, 6}

'&' 기호를 사용하면 교집합을 간단히 구할 수 있다.
또는 다음과 같이 intersection 함수를 사용해도 동일한 결과를 돌려준다.

s1 = set([1, 2, 3, 4, 5, 6])
s2 = set([4, 5, 6, 7, 8, 9])

print(s1.intersection(s2))
>>> {4, 5, 6}

s2.intersection(s1)을 사용해도 결과는 같다.

합집합
합집합은 다음과 같이 구할 수 있다. 이때 4, 5, 6 처럼 중복해서 포함된 값은 한 개씩만 표현된다.

s1 = set([1, 2, 3, 4, 5, 6])
s2 = set([4, 5, 6, 7, 8, 9])

print(s1 | s2)
>>> {1, 2, 3, 4, 5, 6, 7, 8, 9}

'|' 기호를 사용한 방법이다.

s1 = set([1, 2, 3, 4, 5, 6])
s2 = set([4, 5, 6, 7, 8, 9])

print(s1.union(s2))
{1, 2, 3, 4, 5, 6, 7, 8, 9}

또는 union 함수를 사용하면 된다. 교집합에서 사용한 intersection 함수와 마찬가지로 s2.union(s1)을 사용해도 동일한 결과를 돌려준다.

차집합
차집합은 다음과 같이 구할 수 있다.

s1 = set([1, 2, 3, 4, 5, 6])
s2 = set([4, 5, 6, 7, 8, 9])

print(s1 - s2)
>>> {1, 2, 3}

print(s2 - s1)
>>> {8, 9, 7}

빼기 (-) 기호를 사용한 방법이다.

s1 = set([1, 2, 3, 4, 5, 6])
s2 = set([4, 5, 6, 7, 8, 9])

print(s1,difference(s2))
>>> {1, 2, 3}

print(s2.difference(s1))
>>> {8, 9, 7}

difference 함수를 사용해도 차집합을 구할 수 있다.


6.4) 집합 자료형 관련 함수

값 1개 추가하기(add)
이미 만들어진 set 자료형에 값을 추가할 수 있다. 1개의 값만 추가(add)할 경우에는 다음과 같이 한다.

s1 = set([1, 2, 3])
s1.add(4)

print(s1)
>>> {1, 2, 3, 4}

값 여러 개 추가하기(update)
여러 개의 값을 한꺼번에 추가(update)할 때는 다음과 같이 하면 된다.

s1 = set([1, 2, 3])
s1.update([4, 5, 6])

print(s1)
>>> {1, 2, 3, 4, 5, 6}

특정 값 제거하기(remove)
특정 값을 제거하고 싶을 때는 다음과 같이 하면 된다.

s1 = set([1, 2, 3])
s1.remove(2)

print(s1)
>>> {1, 3}

7. 불 자료형

7.1) 불 자료형이란?

불(bool) 자료형이란 참(True)과 거짓(False)을 나타내는 자료형이다. 불 자료형은 다음 2가지 값만을 가질 수 있다.

  • True: 참
  • False: 거짓

다음과 같이 변수 a에는 True를, 변수 b에는 False를 지정해 보자.

a = True
b = False

따옴표로 감싸비 않은 문자열을 변수에 지정해서 오류가 발생할 것 같지만 잘 실행된다. type 함수를 변수 a와 b에 사용하면 두 변수의 자료형이 bool로 지정된 것을 확인할 수 있다.

a = True
b = False

print(type(a))
>>> <class 'bool'>

print(type(b))
>>> <class 'bool>

불 자료형은 조건문의 반환 값으로도 사용된다. 조건문에 대해서는 if문에서 자세히 배우겠지만 잠시 살펴보고 넘어가자.

1 == 1
>>> True

1 == 1 은 '1과 1이 같은가?' 를 묻는 조건문이다. 이런 조건문은 결과 True 또는 False에 해당하는 불 자료형을 돌려준다. 1과 1은 같으므로 True를 돌려준다.

2 > 1
>>> True

2는 1보다 크기 때문에 2 > 1 조건문은 True를 돌려준다.

2 < 1
>>> False

2는 1보다 작지 않기 때문에 2 < 1 조건문은 False를 돌려준다.


7.2) 자료형의 참과 거짓

자료형에 참과 거짓이 있다? 조금 이상하게 들리겠지만 참과 거짓은 분명히 있다. 이는 매우 중요한 특징이며 실제로도 자주 쓰인다.

자료형의 참과 거짓을 구분하는 기준은 다음과 같다.

자료형참 or 거짓
문자열"python"
""거짓
리스트[1, 2, 3]
[]거짓
튜플()거짓
딕셔너리{}거짓
숫자형0이 아닌 숫자
0거짓

문자열, 리스트, 튜플, 딕셔너리 등의 값이 비어 있으면 ("", [], (), {}) 거짓이 된다. 당연히 비어 있지 않으면 참이 된다. 숫자에서는 그 값이 0일 때 거짓이 된다. 위 표애는 None이 없는데, 이것에 대해서는 뒷부분에서 배우니 아직은 신경 쓰지 말자. 그저 None은 거짓을 뜻한다는 것만 알아두자.

다음 예를 보고 참과 거짓이 프로그램에서 어떻게 쓰이는지 간단히 알아보자.

a = [1, 2, 3, 4]
while a:
	a.pop()
    print(a)
   
>>> 4
    3
    2
    1

먼저 a = [1, 2, 3, 4] 리스트를 하나 만들었다.

while문은 나중에 자세히 다루겠지만 간단히 알아보면 다음과 같다. 조건문이 참인 동안 조건문 안에 있는 문장을 반복해서 수행한다.

즉, 위 예를 보면 a가 참인 경우에 a.pop()을 계속 실행하라는 의미이다. a.pop() 함구는 리스트 a의 마지막 요소를 끄집어내는 함수이므로 리스트 안에 요소가 존재하는 한 마지막 요소를 계속해서 끄집어낼 것이다. 결국 더 이상 끄집어낼 것 없으면 a가 빈 리스트([])가 되어 거짓이 된다. 따라서 while문에서 조건이 거짓이 되므로 중지된다. 위에서 본 예는 파이썬 프로그래밍에서 매우 자주 사용하는 기법 중 하나이다.

위 예가 너무 복잡하다고 생각하는 독자는 다음 예를 보면 쉽게 이해될 것이다.

if []:
	print("참")
else:
	print("거짓")

>>> 거짓

[]는 앞의 표에서 볼 수 있듯이 비어 있는 리스트이므로 거짓이다. 따라서 '거짓'이란 문자열이 출력된다. if문에 대해서 잘 모르는 독자라도 위 문장을 해석하는 데는 무리가 없을 것이다.

if [1, 2, 3]:
	print("참")
else:
	print("거짓")
    
>>>

위 코드를 해석해 보면 다음과 같다.

만약 [1, 2, 3]이 참이면 "참"이라는 문자열을 출력하고 그렇지 않으면 "거짓"이라는 문자열을 출력하라

위 코드의 [1, 2, 3]은 요솟값이 있는 리스트이기 때문에 참이다. 따라서 "참"을 출력한다.


7.3) 불 연산

자료형에 참과 거짓이 있음을 이미 알아보았다. bool 내장 함수를 사용하면 자료형의 참과 거짓을 식별할 수 있다.

다음 예제를 따라 해 보자.

bool('python')
>>> True

'python' 문자열은 빈 문자열이 아니므로 bool 연산의 결과로 불 자료형인 True를 돌려준다.

bool('')
>>> False

문자열은 빈 문자열이므로 bool 연산의 결과로 불 자료형인 False를 돌려준다.

위에서 알아본 몇 가지 예제를 더 수행해 보자.

bool([1, 2, 3])
>>> True

bool([])
>>> False

bool([0])
>>> False

bool(3)
>>> True

위에서 알아본 것과 동일한 참과 거짓에 대한 결과를 돌려주는 것을 확인할 수 있다.


8. 자료형의 값을 저장하는 공간, 변수

지금부터 설명할 내용은 프로그래밍 초보자가 얼른 이해하기 어려운 부분이므로 당장 이해가 되지 않는다면 그냥 건너뛰어도 된다. 파이썬에 대해서 공부하다 보면 자연스럽게 알게 될 것이다.

우리는 앞에서 이미 변수를 사용해 왔다. 다음 예와 같은 a, b, c를 변수라고 한다.

a = 1
b = "python"
c = [1, 2, 3]

변수를 만들 때는 위 예처럼 =(assignment) 기호를 사용한다.

다른 프로그래밍 언어인 C나 JAVA에서는 변수를 만들 때 자료형을 직접 지정해야 한다. 하지만 파이썬은 변수에 저장된 값을 스스로 판단하여 자료형을 저장하기 때문에 더 편리하다.

8.1) 변수란?

파이썬에서 사용하는 변수는 객체를 가리키는 것이라고도 말할 수 있다. 객체란 우리가 지금껏 보아 온 자료형과 닽은 것을 의미하는 말이다.

a = [1, 2, 3]

만약 위 코드처럼 a = [1, 2, 3]이라고 하면 [1, 2, 3] 값을 가지는 리스트 자료형이 자동으로 메모리에 생성되고 변수 a는 [1, 2, 3] 리스트가 저장된 메모리의 주소를 가리키게 된다.

a 변수가 가리키는 메모리의 주소는 다음과 같이 확인할 수 있다.

a = [1, 2, 3]

print(id(a))
>>> 4303029896

id 한수는 변수가 가리키고 있는 객체의 주소 값을 돌려자는 파이썬 내장 함수이다. 즉 여기에서 필자가 만든 변수 a가 가리키는 [1, 2, 3] 리스트의 주소 값은 4303029896 임을 알 수 있다.


8.2) 리스트를 복사할 때

여기에서는 리스트 자료형에서 가장 혼동하기 쉬운 '복사'에 대해 설명하겠다. 다음 예를 통해 알아보자.

a = [1, 2, 3]
b = a

b 변수에 a 변수를 대입하면 어떻게 될까? b와 a는 다른 걸까? 결론부터 말하면 b는 a와 완전히 동일하다고 할 수 있다. 다만 [1, 2, 3] 리스트를 참조하는 변수가 a 변수 1개에서 b 변수가 추가되어 2개로 늘어났다는 차이만 있을 뿐이다.

id 함수를 사용하면 이러한 사실을 확인할 수 있다.

a = [1, 2, 3]
b = a

print(id(a))
>>> 4303029896

print(id(b))
>>> 4303029896

id(a)의 값이 id(b)의 값과 동일함을 확인할 수 있다. 즉 a가 가리키는 대상과 b가 가리키는 대상이 동일하다는 것을 알 수 있다. 동일한 객체를 가리키고 있는지에 대해서 판단하는 파이썬 명령어 is를 다음과 같이 실행해도 역시 참(True)을 돌려준다.

a = [1, 2, 3]
b = a

print(a is b)
>>> True

이제 다음 예를 계속해서 수행해 보자.

a = [1, 2, 3]
b = a

a[1] = 4
print(a)
>>> [1, 4, 3]

print(b)
>>> [1, 4, 3]

a 리스트의 두 번째 요소를 값 4로 바꾸었더니 a 만을 바뀌는 것이 아니라 b도 똑같이 바뀌었다.

그 이유는 앞에서 살펴본 것처럼 a, b 모두 동일한 리스트를 리스트를 가리키고 있기 때문이다. 그렇다면 b 변수를 생성할 때 a 변수의 값을 가져오면서 a와 다른 주소를 가리키도록 만들수는 없을까? 다음 2가지 방법이 있다.

1. [:] 사용
첫 번째 방법으로는 다음과 같이 리스트 전체를 가리키는 [:]을 사용해서 복사하는 것이다.

a = [1, 2, 3]
b = a[:]
a[1] = 4

print(a)
>>> [1, 4, 3]

print(b)
>>> [1, 2, 3]

위 예에서 볼 수 있듯이 a 리스트 값을 바꾸더라도 b 리스트에는 영향을 끼치지 않는다.

2. copy 모듈 사용
두 번째 copy 모듈을 사용하는 방법이다. 다음 예를 보면 from copy import copy 라는 처름 보는 형태의 문장이 나오는데, 이것은 뒤에 설명할 파이썬 모듈 부분에서 자세히 다룬다. 여기에서는 단순히 copy 함수를 쓰기 위해서 사용하는 것이라고만 알아두자.

from copy import copy
a = [1, 2, 3]
b = copy(a)

위 예에서 b = copy(a)는 b = a[:]과 동일하다.

두 변수가 같은 같을 가지면서 다른 객체를 제대로 생성했는지 다음과 같이 확인해 보자.

from copy import copy
a = [1, 2, 3]
b = copy(a)

print(a)
>>> [1, 2, 3]

print(b)
>>> [1, 2, 3]

print(b is a)
>>> False

위 예에서 b is a가 False를 돌려주므로 b와 a가 가리키는 객체는 서로 다르다는 것을 알 수 있다.


8.3) 변수를 만드는 여러 가지 방법

a, b = ('python', 'Life')

위 예문처럼 튜플로 a, b에 값을 대입할 수 있다. 이 방법은 다음 예문과 완전히 동일하다.

(a, b) = 'python', 'Life'

튜플 부분에서도 언급했지만 튜플은 괄호를 생략해도 된다.

다음처럼 리스트로 변수를 만들 수도 있다.

[a, b] = ['python', 'Life']

또한 여러 개의 변수에 같은 값을 대입할 수도 있다.

a = b = 'python'

파이썬에서는 위 방법을 사용하여 두 변수의 값을 아주 간단히 바꿀 수 있다.

a = 3
b = 5
a, b = b, a

print(a)
>>> 5

print(b)
>>> 3

처음에 a에 값 3, b에는 값 5가 대입되어 있었지만 a, b = b, a 문장을 수행한 후에는 그 값이 서로 바뀌었음을 확인할 수 있다.

profile
With passion and honesty

0개의 댓글