Python 데이터의 비밀

타키탸키·2021년 1월 20일
0

Python 입문하기

목록 보기
10/14
post-thumbnail

지금까지 Python의 새로운 자료형 list와 dictionary, 그리고 for반복문을 함께 배워봤습니다. 이를 통해 여러분은 Python을 활용한 데이터 처리 방법을 간략하게 체험할 수 있었습니다. 이번 시간에는 Python 데이터가 지니는 비밀에 대해 함께 알아보는 시간을 가져보겠습니다.

🤐 Aliasing

x = 4
y = x
y = 2
print(x)
print(y)

위 코드를 실행하면 어떤 값들이 출력될까요? 우선 변수 x에는 4라는 수가 저장되고 y에도 x의 값 4가 저장됩니다. 바로 이어지는 줄에서 y에 새로운 값 2가 저장됩니다. 결과적으로 두 값을 출력하면 4와 2가 나옵니다.

x = [1, 1, 2, 3, 5]
y = x
y[3] = 5
print(x)
print(y)

그렇다면 위 코드로는 어떤 값들이 출력될까요? 다시 차근차근 살펴봅시다. 변수 x에 리스트가 지정되었습니다. 다음으로 y가 x값을 받으므로 똑같이 리스트를 가지게 됩니다. 그 다음 줄에서 인덱스 3에 5라는 값이 대체될 것입니다. 그 후, x와 y를 출력하면 다음과 같은 결과가 나옵니다.

[1, 1, 2, 5, 5]
[1, 1, 2, 5, 5]

두 결괏값이 같습니다. y는 요소가 대체된 새로운 리스트이고 x는 기존의 리스트일텐데 두 결괏값이 동일한 이유는 무엇일까요?

Python에서 어떤 변수에 값을 지정하는 것은 해당 값에 이름표를 붙여주는 것과 같다고 생각하면 됩니다. 즉, 맨 위 코드에서 x에 4라는 값을 지정한 것은 4라는 값에 x라는 이름표를 달아준 것과 같다고 할 수 있습니다.

그리고 뒤이어 y에 x를 지정해주면 같은 값에 대해 y라는 또 다른 이름을 붙여주게 됩니다. 이 상태에서 y에 새로운 값 3을 지정해주면 이번에는 이름표가 3이라는 값에 붙여지게 됩니다. 이런 식으로 하나의 이름표는 하나의 값에만 붙일 수 있습니다.

이번에는 두번째 코드와 같이 정수형이 아닌 리스트를 변수에 지정해주는 경우를 살펴봅시다. 리스트 역시 값과 마찬가지로 변수 x에 지정되면 x라는 이름표를 갖게 됩니다. 그 다음 줄에서 y라는 이름표를 새로 갖게 되는 것도 똑같죠.

이제 그 다음 줄에서 y의 요소를 바꾸게 됩니다. 해당 리스트는 요소가 바뀌긴 했지만 이미 x와 y라는 이름표를 둘다 가지고 있습니다. 따라서, x와 y 모두 동일한 결괏값을 출력하는 것이죠. 이때, y를 x의 가명 혹은 Alias라고 부릅니다. y와 x는 서로 다른 이름이지만 사실 같은 값을 가지고 있죠.

그렇다면 본래 의도한대로 y는 대체된 리스트로, x는 기존의 리스트로 출력하려면 어떻게 해야할까요? 다음 코드를 봅시다.

x = [1, 1, 2, 3, 5]
y = list(x)
y[3] = 5
print(x)
print(y)

이번에는 두번째 줄에 변수 x대신 리스트 함수를 사용했습니다. 이렇게 하면 첫번째 리스트에 x라는 이름이 달리고 두번째 줄에서 리스트 함수로 인해 리스트 x가 그대로 복사되면서 새로운 리스트가 만들어집니다. 그리고 이 새롭게 만들어진 리스트에 y라는 이름표가 붙는 것이죠.

이후에는 y의 요소를 바꾸게 되면서 결과적으로 x와 y가 서로 다른 리스트를 가지게 됩니다. 이 경우에 y는 더이상 x의 Alias가 아닙니다. y의 요소가 바뀌어도 기존의 리스트도 변하지 않죠. 따라서, 출력값도 서로 다르게 나옵니다.

[1, 1, 2, 3, 5]
[1, 1, 2, 5, 5]

그런데 앞서 하나의 값은 하나의 이름표만 가질 수 있다고 했습니다. 하지만 리스트는 두 가지 이름표를 가졌는데요. 어떻게 된 걸까요? 리스트는 사전과 함께 가변형 자료형에 속합니다. 가변형 자료형이란, 이름 그대로 변형이 가능한 자료형이라는 뜻을 지닙니다.

반대로 int, str, bool과 같은 자료형은 불변형입니다. 값이 바뀌지 않는다는 뜻이죠. 이처럼 하나의 이름표는 하나의 값에만 붙일 수 있다는 말은 이와 같은 불변형 자료형에만 해당하는 이야기입니다.

🤐 리스트와 문자열

리스트는 문자열과 유사한 구조를 지니고 있습니다. 문자열이 문자를 나열하는 것처럼 리스트도 특정 자료형을 나열한 것이기 때문이죠. Python에서 문자열과 리스트의 유사점과 차이점에 대해 알아보겠습니다.

list_alphabets = ['j', 'e', 'a', 'l', 'o', 'u', 's', 'y']

print(list_alphabets[2])
print(list_alphabets[3])
print(list_alphabets[6])
print(list_alphabets[-3])

❗ 인덱싱(indexing)

위 코드는 인덱싱을 통해 리스트의 요소를 불러옵니다. 흥미로운 것은 문자열을 통해서도 이와 같이 인덱싱이 가능하다는 점입니다.

str_alphabets = 'jealousy'

print(str_alphabets[2])
print(str_alphabets[3])
print(str_alphabets[6])
print(str_alphabets[-3])

이처럼 문자열에서 특정 문자를 추출하는 코드는 리스트와 매우 유사합니다. 문자열에서도 마찬가지로 인덱스가 0부터 시작합니다. 따라서 두 코드는 같은 결괏값을 추출하게 됩니다.

❗ 슬라이싱(slicing)

리스트 슬라이싱도 함께 볼까요?

list_alphabets = ['j', 'e', 'a', 'l', 'o', 'u', 's', 'y']

print(list_alphabets[2:7])
print(list_alphabets[6:])
print(list_alphabets[:6])
['a', 'l', 'o', 'u', 's']
['s', 'y']
['j', 'e', 'a', 'l', 'o', 'u']

우선, [2:7]은 인덱스 2부터 6까지의 요소가 담긴 리스트라는 사실 기억하시죠? 따라서, 인덱스 2인 'a'부터 6인 's'까지 'a', 'l', 'o', 'u', 's'가 있는 새로운 리스트가 만들어집니다.

다음으로 [6:]는 인덱스 6부터 시작해서 리스트의 끝까지를 추출하기 때문에 's'와 'y'가 담긴 리스트를 생성합니다. [:6]는 시작지점이 없고 인덱스 5까지를 추출하므로 인덱스 0부터 5까지를 추출합니다. 그러면 'j', 'e', 'a', 'l', 'o', 'u'가 담긴 리스트가 생성되겠죠?

이러한 슬라이싱 개념은 문자열에서도 똑같이 적용됩니다. 일명 문자열 슬라이싱인 셈이죠.

str_alphabets = 'jealousy'

print(str_alphabets[2:7])
print(str_alphabets[6:])
print(str_alphabets[:6])
alous
sy
jealou

위 코드를 출력해보면 리스트 슬라이싱과 동일한 결과가 출력됩니다. 차이점이라면 리스트 슬라이싱의 경우 리스트를 생성하는 반면에 문자열 슬라이싱은 새로운 문자열을 생성한다는 것입니다.

❗ 덧셈 연산

문자열을 배울 때, 연산을 통해 문자열을 연결하는 방법이 있었다는 사실, 기억하시나요? 리스트도 마찬가지로 연산을 통해 연결이 가능합니다.

str_1st = 'Hello,'
str_2nd = 'World!'
str_3rd = str_1st + str_2nd
print(str_3rd)

list_1st = [1, 1, 2, 3]
list_2nd = [5, 8, 13, 21]
list_3rd = list_1st + list_2nd
print(list_3rd)
Hello,World!
[1, 1, 2, 3, 5, 8, 13, 21]

❗ len함수

우리는 리스트 요소의 개수를 구할 때, len함수를 사용했습니다. 문자열 또한 len함수를 사용하여 문자의 개수를 구할 수 있습니다.

some_list = [1, 1, 2, 3, 5]
print(len(some_list))

some_string = 'Hello World'
print(len(some_string))
5
11

주의할 것은 문자를 셀 때, 공백도 포함된다는 점입니다.

❗ for 반복문

마지막으로 두 자료형 모두 인덱싱이 가능한만큼 for반복문에서 유사하게 활용이 가능합니다.

# 리스트 반복문
list_alphabets = ['T', 'A', 'K', 'I']
for alphabets in alphabets_list:
    print(alphabets)
    
# 문자열 반복문
str_alphabets = 'TAKI'
for alphabets in str_alphabets:
    print(alphabets)
T
A
K
I

T
A
K
I

❗ 차이점

지금까지 리스트와 문자열의 유사점을 알아봤습니다. 그렇다면 이 두 개념의 차이점에는 어떤 것들이 있을까요?

nums = [1, 1, 2, 3]
nums[2] = 4
print(nums)

위 코드의 두번째 줄에서 인덱스 2의 값을 4로 변경했습니다. 이렇게 하면 리스트가 [1, 1, 4, 3]으로 바뀌겠죠? 문자열로도 한 번 해보겠습니다.

name = 'Valerie'
name[0] = 'v'
print(name)

위 코드를 실행하면 오류가 나옵니다! 😧 왜일까요? 문자열은 리스트와 달리 수정이 불가능한 불변형 자료형이기 때문입니다. 앞서 가변형 자료형과 불변형 자료형에 대해 배웠던 것을 기억하시나요? 그와 같은 개념입니다.

하지만 우리는 앞서 문자열 연산을 통해 문자열을 서로 연결하면서 변형을 했었는데요. 이 것이 가능했던 이유는 뭘까요? 면밀히 따져보면 이 연산에서는 문자열을 변형한 것이 아니라 단지 서로 다른 문자열들을 붙여서 새로운 문자열을 만들었을 뿐이기 때문입니다. 즉, 고유의 문자열을 수정하진 않았다는 얘기죠.

요컨대, 문자열과 리스트의 대표적인 차이점자료형의 가변성에 있다고 보면 됩니다. 수정이 되는 가변형 자료형 리스트와 수정이 불가능한 불변형 자료형 문자열로 말이죠.


이번 시간에는 Python 데이터의 비밀을 알아보며 데이터의 이름표 Alising과 자료형 리스트와 문자열의 유사점 및 차이점에 대해 배웠습니다. 또한, 자료형의 특징을 나누는 기준인 가변성과 불변성에 대해서도 함께 알아보았는데요. 이번 시간에 배운 내용을 가지고 Python의 데이터에 대해 좀 더 깊이 이해할 수 있게 되었길 바랍니다.

* 이 자료는 CODEIT의 프로그래밍 기초 in Python을 기반으로 작성되었습니다.
profile
There's Only One Thing To Do: Learn All We Can

0개의 댓글