파이썬 자료구조 2-1장. 자료구조와 배열

1. 리스트와 튜플 알아보기


파이썬에서 배열을 리스트와 튜플로 구현할 수 있다. 리스트와 튜플은 데이터 컨테이너라고 하며, 비슷한 기능을 하는 듯 하지만 원소를 변경할 수 있는지 없는지에 따라 차이가 있다.

리스트의 기초

리스트의 원소 개수는 리스트를 만들기 전에 반드시 결정해야 한다. 하지만 원솟값을 정하지 않는 리스트는 None을 사용하면 만들 수 있다.

# 직접 구성
list01 = [] # 빈 리스트
list02 = [1,2,3] # [1,2,3]
list03 = ['A','B','C',] # ['A','B','C'] # 맨 마지막 원소에 쉼표를 써도 됨
# 내장 함수 사용
list04 = list() # 빈 리스트
list05 = list('ABC') # ['A','B','C'] # 문자열의 각 문자로부터 원소 생성
list06 = list((1,2,3))  # 튜플로부터 원소 생성 반드시 괄호 2쌍
list07 = list({1,2,3}) # 집합으로부터 원소 생성
list08 = list([1,2,3]) # 리스트로부터 원소 생성
list09 = list(range(3,8)) # [3,4,5,6,7] 
list10 = [None] * 5 # # [None,None,None,None,None]

튜플의 기초

튜플은 원소에 순서를 매겨 결합한 것으로 원소를 변경할 수 없는 이뮤터블 자료형이다. 원소를 쉼표로 구분하여 나열한 결합 연산자()로 둘러싸는 방식으로 생성한다. 리스트와 마찬가지로 맨 마지막 원소 뒤에 쉼표를 써도 되며, ()만 사용시 빈 튜플을 생성한다. 결합연산자 ()를 생략할 수 있다. 아래의 tuple01, 02 처럼 원소가 1개인 경우 반드시 쉼표를 사용해야한다. 쉼표가 없으면 튜플이 아니라 단순 변수로 여기기 때문이다.

# 직접 구성
tuple01 = () # 빈 튜플
tuple02 = 1, # (1,) 
tuple03 = (1,) # (1,)
tuple04 = 1,2,3 # (1,2,3)
tuple05 = 1,2,3, # (1,2,3)
tuple06 = 'A','B','C' # ('A','B','C')

# 내장 함수 사용
tuple09 = tuple() # 빈 튜플
tuple10 = tuple('ABC') # ('A','B','C')
# 리스트, 집합, range로부터도 원소 생성이 가능하다.

2. 리스트와 튜플 풀어내기: 언팩

좌변에 여러 개의 변수를 놓고 우변에는 리스트나 튜플을 놓으면 우변의 원소를 좌변의 변수에 한번에 대입할 수 있다. 이와 같이 리스트나 튜플의 원솟값들을 풀어 여러 변수에 대입하는 것을 언팩이라고 한다.

x = [1,2,3]
a,b,c = x
print(a,b,c) # 1 2 3

3. 인덱스식 사용하기

리스트나 튜플의 원소에 접근할 때는 인덱스를 사용한다. 존재하지 않는 인덱스 접근시 예외 발생, 존재하지 않는 인덱스에 대입시에도 추가되지 않고 예외가 발생한다.

x = [11,22,33,44,55,66,77]
print(x[0]) # 11
print(x[-1]) # 77
print(x[7]) # 존재하지 않는 인덱스로 오류 출력
print(x[7]) = 3.14 # 존재하지 않는 인덱스에 접근하거나 대입해도 원소가 추가되지 않음.

4. 슬라이스식으로 원소에 접근하기

리스트 또는 튜플의 원소 일부를 연속해서 또는 일정한 간격으로 꺼내 새로운 리스트 또는 튜플을 만드는 것을 슬라이스라고 한다.

s[i:j] # s[i] 부터 s[j-1]까지 나열한다.
s[i:j:k] # s[i] 부터 s[j-1]까지 k씩 건너뛰며 나열한다.
  • i,j가 len(s)보다 크면 len(s)가 지정된 것으로 간주된다. 따라서 인덱스와 달리 범위에서 벗어나는 값을 지정해도 오류가 발생하지 않는다.
  • i가 없거나 None이면 0이 지정된 것으로 간주한다.
  • j가 없거나 None이면 len(s)가 지정된 것으로 간주한다.
  • j가 i보다 작으면 비어있는 상태로 출력
패턴설명
s[:]리스트 s의 원소를 모두 출력
s[:n]리스트 s의 원소 중 맨 앞에서부터 s[n-1]까지 출력
s[i:]리스트 s의 원소 중 s[i]부터 끝까지 출력
s[-n:]리스트 s의 원소 중 s[-n]부터 끝까지 출력
s[::k]리스트 s의 원소 중 맨 앞에서부터 k개씩 건너뛰며 출력
s[::-1]리스트 s의 원소를 역순으로 출력
# 예시
s = [11,22,33,44,55,66,77]
print(s[0:6]) # 11,22,33,44,55,66
print(s[0:7:2]) # 11 33 55 77
print(s[-4:-2]) # 44 55
print(s[3:1]) # []  # j값이 i값보다 작지만 오류가 나지 않음


뮤터블과 이뮤터블의 대입

  • 뮤터블 자료형 : 리스트, 딕셔너리, 집합 등이 있으며 값을 변경할 수 있다.
  • 이뮤터블 자료형 : 수, 문자열, 튜플 등이 있으며 값을 변경할 수 없다.
n = 5
print(id(n))
n='abc'
print(id(n))

n이 참조하는 곳이 int형인 정수 5에서 str형인 문자열로 업데이트 된 것이다. 당연히 int형 객체 5의 값 자체는 바뀌지 않고 n이 참조하는 식별번호가 바뀐것 이다.

x=6
y=2
x,y = y+2, x+3
print(x,y) # 4 9

두 대입식이 동시에 이루어지므로 x는 업데이트되기 전의 값인 6으로 계산이 진행된다.

정수를 나타내는 int형과 문자열을 나타내는 str형은 값을 변경할 수 없다. 이렇게 값을 변경할 수 없는 특성을 이뮤터블이라고 하며, 값을 변경할 수 있는 특성은 뮤터블이다. 이유는 위에서 말했듯이 변수는 객체의 값 자체를 변경하는 것이 아니라 참조하는 것일 뿐이기 때문이다. 만약 n= 5 에서 n=13 으로 코딩했다고 가정하면 n은 5인 int형 객체를 참조하다가 13인 int형 객체로 참조를 업데이트한 것이다. int형 객체가 변경된 것이 아니다.

cf) 파이썬의 대입

  • 좌변에 변수 이름이 처음 나온 경우, 그 변수에 맞는 자료형으로 자동 선언해준다.
  • 대입식은 값 자체가 아니라 참조하는 객체의 식별 번호를 대입한다.
  • 여러 변수에 여러 값을 한꺼번에 대입할 수 있다.
  • 대입 기호 =를 연산식에서 사용하는 +,* 등과 같이 취급하지 않는다.
    • x + 17은 식이지만 x = 17은 식이 아니다. type(x + 17) # int ,, type(x = 17) # 예외 발생
    • = 대입기호는 식이 아니라 문이므로 자료형을 확인 할 수 없다.
  • C언어 Java등 다른 언어에서는 =를 결합 연산자로 사용하기때문에 a=b=1 과 같이 a=(b=1)이라는 의미로 사용한다. 하지만 파이썬에서는 =는 연산자가 아니므로 결합을 할 수 없다. 따라서 a=b=1 의 경우 파이썬에서는 a=1 먼저 실행하고 b=1을 실행한다. 되도록이면 a=1 , b=1 과 같이 따로 사용하도록 하자.

5. 빈 배열 판단하기

배열에 원소가 하나도 없는지 확인하고 싶다면 배열을 참조하는 변수를 조건식에 그대로 사용하면 된다.

if x:
  # x가 비어있지 않으면 실행
else :
  # x가 비어있으면 실행

6. 비교 연산자로 배열의 대소 또는 등가 관계 판단하기

  • 맨 앞 원소부터 차례로 비교하면서 원소의 값이 같으면 다음 원소를 비교한다.
  • 어느 원소 값이 크면 그 배열이 큰 것으로 판단
  • 원소 수가 다른 경우에는 원소 수가 많은 배열이 더 크다고 판단
[1,2,3] < [1,2,3,5] # True
[1,2,3] < [1,2,4] # True

cf) 등가성과 동일성은 다르다
파이썬에서 값을 비교할 때 등가성과 동일성을 사용한다. 등가성 비교는 == 을 동일성 비교는 is 를 사용한다. 등가성 비교는 좌변과 우변의 값이 같은지를 비교하고, 동일성 비교는 값은 물론이고 객체의 식별 번호까지 같은지 비교한다.


본 포스팅은 ‘자료구조와 함께 배우는 알고리즘 입문’을 읽고 공부한 내용을 바탕으로 작성하였습니다.


© 2021. By Backtony