티스토리 뷰

728x90

파이썬 기본 자료 구조 : 배열



※ Python 배열(array,list) 의 기본 틀





설명 : 왼편에 변수명을 선언하고 대괄호 [] 안에 원소들을 넣어줍니다. 원소가 여러 개일 때, ,쉼표로 구분하여 표현해줍니다. 위의 리스트는 강원도, 경기도, 경상도, 전라도, 충청도 5개 원소로 구성되어 있습니다.


출처 : https://velog.io/@ybnr_92/Python-list



파이썬에서 배열은 list라고도 하는데 배열이란 여러 자료형들을 하나의 묶음으로 관리하고 각 원소간에는 순서(order)가 존재해서 인덱스(index)를 통해 접근이 가능한 자료형을 말합니다. 다시 말해서 배열 안에는 여러가지 자료형들이 들어갈 수 있으며, 그 원소 각각에는 순서가 있어 index를 통해 각 원소에 접근할 수 있습니다.

배열 즉 리스트는 정말 유용하고 많이 사용하며 기본적인 자료 구조이기 때문에 잘 활용할 수 있도록 합시다.😍
이제 배열에 있는 여러 operation들을 통해 공부해봅시다. 😊



1. 리스트 만들기


리스트를 사용하면 다양한 원소들의 모음을 만들 수 있습니다.

odd = [], add1 = list()
odd2 = [1,3,5,6,8] 
odd3 =  ["안녕", 1, 3, 5, [1,5], True]
odd4 = ["python", False, 1,3,5, [1,3,5]]

보시는 것과 같이 list를 선언만 할수도 있으며 list안에 한 원소로만 구성될수도 있고 다양한 원소로도 구성되어 있을 수 있습니다.




2. 리스트 인덱싱과 슬라이싱


list는 문자열처럼 인덱싱과 슬라이싱을 할 수 있는데 이때 인덱싱이라 함은 처음에 말한 것처럼 리스트에는 인덱싱이 붙어 있습니다.

odd = [1,2,3]

이 변수에서 첫 번째 원소는 1입니다. 그럼 이를 표현할 때에는


odd[0]
> 1

odd[-1]
> 3

이렇게 표현해줍니다. 언어마다 인덱싱의 시작번호가 다를 수 있는데 python에서는 첫 원소의 시작을 0으로 합니다. 또 마지막 원소를 가리킬 때는 -1 인덱스를 사용합니다.


odd[0] + odd[1]
> 3

이렇게 인덱싱을 통해 값에 접근하여 operation을 해줄 수 있습니다.
그럼 슬라이싱이란 무엇일까요?

표현 식 : 변수[start index, end index, interval]


odd[0:2]
> [1,2]

슬라이싱이란 본 뜻은 '나눈다'는 뜻입니다.

string = '1234'

string[1:3]
> '23'
string[:3]
> '123'
string[0:3:2]
> '13'

주의 😡


슬라이싱을 할 때 주의해야할 점은 마지막 인덱싱은 포함되지 않는다는 점입니다. 즉 지금 보시면 [1:3]까지 슬라이싱을 하지만 1,2 인덱스에 해당하는 값만 표현됩니다.



3. 리스트 연산하기

리스트는 +* 연산을 할 수 있는데 살펴봅시다


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

a + b
> [1,2,3,4]

리스트를 더하게 되면 각 리스트의 원소들이 하나의 리스트로 결합되는 걸 볼 수 있습니다.
* 연산을 한다면


a * 3
> [1,2,1,2,1,2]

* 연산은 해당 리스트의 원소들을 곱해준 수만큼 반복해서 한 리스트에 포함시킵니다.


주의 😡

다른 타입의 원소끼리 연산을 할 때 입니다.

a = [1,2,3,4,5]
a[0] + "안녕"
TypeError Traceback (most recent call last) in 
      1 a = [1,2,3]
----> 2 a[0] + "안녕"
      3 a
TypeError: unsupported operand type(s) for +: 'int' and 'str'

이건 꼭 리스트에서 뿐만이 아니라 모든 연산에서 적용되는 것이므로 조심합니다.




3-1. 리스트 파악하기

1) 리스트 길이 구하기

리스트의 길이를 구할 때는 len()이라는 코드를 씁니다.

a = [1,2,3]

len(a)
> 3



2) 리스트 원소 수정하기

리스트의 각 원소를 인덱스로 접근하여 해당 인덱스의 원소값을 수정할 수 있습니다.

a = [1,2,3,4]
a[0] = 10

a
> [10,2,3,4]



3) 리스트 원소 추가하기

해당 리스트에 자신이 원하는 원소를 추가할 수 있습니다. 이때 두 가지 방법이 있는데 하나는 append() 입니다.

a = [1,2,3]
a.append(4)

a
> [1,2,3,4]

append() 라는 기능을 이용하면 해당 리스트에 원하는 원소를 뒤로 추가 시킵니다. 이때 원소의 타입은 다양하게 할 수 있습니다.


다른 방법은 insert() 기능을 사용하는 것입니다.


a = [1,2,3]
a.insert(0,4)

a
> [4,1,2,3]

insert() 함수는 append() 와 달리 원하는 인덱스 자리에 원하는 원소를 추가할 수 있습니다.




4) 리스트에서 원소 삭제하기(del,clear,remove())


python 에서 자체적으로 가지고 있는 기능인 del을 사용하여 리스트에서 원하는 원소를 삭제할 수 있습니다.

a = [1,2,3]
del a[0]

a
> [2,3]
a = [1,2,3,4,5]
del a[:3]

a
> [5]

del 기능을 사용하면 원하는 인덱스의 원소 값이 삭제됩니다. 또 여러 값도 동시에 제거할 수 있습니다.

clear()함수는 모든 원소를 제거 할 수 있습니다. 기능적으로 del a[:]와 동일합니다.

a = [1,2,3]
a.clear()

a
> []

remove() 함수를 이용하여 리스트 원소 값을 제거 할 수 있습니다.

a = [1,2,3,4,1]
a.remove(1)

a
> [2,3,4,1]

a.remove(1)

a
> [2,3,4]

이때 주의할 점은 remove 함수에는 원소 값을 넣어야 합니다. 인덱스 값을 넣는 것이 아닙니다. 또한 처음 나온 원소값 하나만을 제거해주기 때문에 주의합니다.




5) 리스트 원소 값 정렬하기(sort, sorted의 차이 구분)


sort() 함수를 사용하여 리스트의 원소 값들을 내림차순, 오름차순으로 정렬을 할 수 있습니다.

a = [1,4,2,3]
a.sort()

a
> [1,2,3,4] # a 변수 원소 값이 정렬되었다.

주의 😡

sort()를 사용하면 해당 리스트 변수의 원래 값에 적용되기 때문에 이를 인지하여 사용하여야 합니다. 반면 sorted()라는 함수를 사용하면 해당 리스트의 값은 변하지 않지만, 정렬기능이 이루어졌을 때의 원소 값이 출력됩니다.


a = [1,5,3,2,4]

sorted(a)
>[1,2,3,4,5] # a 변수의 원소 값만 가지고 사용

a
> [1,5,3,2,4] # a 변수의 값은 그대로이다.

저는 이를 어떻게 구분하냐면, sort()a.sort()라고 쓰이고, sorted()sorted(a)라고 사용됩니다 sort는 a라는 리스트에 접근하여 그 변수의 값을 정렬한다고 보고, sorted()는 a의 변수에 접근하는 것이 아니라 a의 데이터를 사용하여 그 값만 사용한다고 인식합니다.

sort()함수는 기본적으로 오름차순으로 정해있지만 내림차순으로 사용할수도 있습니다.

a = [1,5,3,2,4]
a.sort(reverse=True)

a
> [5,4,3,2,1]

Default 값은 sort(reverse=False) 이기 때문에 오름차순으로 나온 것입니다.




6) 리스트 뒤집기(reverse(), reversed())


정렬을 시키는 sort()에서 사용하는 reverse 변수는 내림차순으로 바꾸어주는 것이고, 여기서 사용하는 reverse, reversed함수는 리스트를 뒤집는 것이므로 주의합니다.

a = [1,4,2,3]
a.reverse()

a
> [3,2,4,1]

결과를 보시면 리스트값이 반대로 된 것을 알 수 있습니다. 내림정렬이 아닙니다!!!

a = [1,4,2,3]

reversed(a)
<list_reverseiterator at 0x14d6a5c2808>

reversed() 함수는 값을 반환하긴 하지만 list_reverseiterator라는 객체를 반환합니다. 그래서 이를 다시 출력하기 위해서는 list()를 사용해야합니다

list(reversed(a))
> [3,2,4,1]

a
> [1,4,2,3]

위에서 봤던 sort()sorted()의 차이와 같이 reversed() 는 원 변수의 값은 변하지 않지만 그 원소값들만을 사용하여 변한 값을 반환해줍니다.




7) 리스트 위치 반환하기(index())


리스트는 인덱싱을 할 수 있다고 했습니다. a[0] 이런 식으로 a 변수의 첫 번째 값에 접근할 수 있는데 반대로 내가 원하는 원소값이 어느 위치에 있는지를 알고 싶을 때가 있습니다. 이때 사용하는 함수가 index() 함수입니다.


a = [10,20,30]

a.index(10)
> 0

index() 함수를 사용하여 10 이라는 원소 값이 0번인덱스에 있다고 나옵니다.

만약 없는 원소 값을 넣으면 어떻게 될까요?

a = [10,20,30]
a.index(40)
ValueError Traceback (most recent call last) in 
      1 a = [10,20,30]
----> 2 a.index(40)
ValueError: 40 is not in list



8) 리스트 원소 값 꺼내기(pop())


pop()함수는 말 그대로 "꺼내다"는 의미를 가지고 있습니다. 꺼내진 값을 사용할 수 있으며, pop()으로 꺼내진 값은 해당 리스트의 값에서 삭제됩니다.

python 자료구조와 알고리즘을 공부하다 보면 빈번하게 선입선출 FIFO(First In, First Out)후입선출LIFO(Last In, First Out) 라는 단어를 들어볼 수 있는데 이를 리스트 자료구조와 pop()함수 를 사용하여 간편하게 작업할 수 있습니다.


a = [1,2,3,4]

a.pop()
> 

a
> [1,2,3]

기본적으로 pop을 사용하면 LIFO, 즉 마지막 들어온 것을 먼저 꺼냅니다. 이는 바닥이 막혀있고 위는 열린 스택구조와도 동일한 기능을 합니다.


a = [1,2,3,4]

a.pop(0)
> 1

a
> [2,3,4]

반대로 FIFO의 구조를 가지고 싶다면 pop()에 첫 인덱스 값을 넣어주기만 하면 됩니다.



9) 리스트 원하는 원소 수 세기( count() )


count() 함수를 사용하여 리스트에서 자신이 원하는 원소의 수를 셀 수 있습니다.

a = [1,4,5,4,2,4]

a.count(4)
> 3



10) 리스트 확장하기 ( extend() )


extend()함수를 사용하여 리스트와 리스트를 합칠 수 있습니다.

a = [1,2,3]
b = [4,5,6]

a.extend(b)

a
> [1,2,3,4,5,6]

extend()함수는 리스트와 리스트를 합치는 것으로 a + b 와 동일한 기능을 수행합니다.




11) 리스트 복사하기 ( copy() )


우선 복사의 개념을 살펴보면 두 가지 경우가 있습니다. 하나는 얕은 복사(shallow copy), 다른 하나는 깊은 복사(deep copy)입니다. 얕은 복사를 알아봅시다.

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

id(a)
> 1432003006152

id(b)
> 1432003006152

a == b
> True

a is b
> True

b[0] = 10
b
> [10,2,3]

a
> [10,2,3]

보시면, a의 아이디와 b의 아이디가 같습니다. a와 b의 원소가 같은가를 물어보면 True값을 반환하고 a가 b인가를 물어보면 True 반환합니다. 즉 a와 b의 아이디가 같고 b를 바꾸면 a도 바뀝니다. import copy에서 copy얕은 복사 를 의미하기 때문에 b.copy.copy(a) 기능을 사용해서 얕은 복사를 할 수 있습니다


우리가 생각할 때 copy는 다른 변수에 같은 원소 값만을 넣고 싶은데 이를 깊은 복사 라고 합니다.
깊은 복사얕은 복사와 다르게 다른 주소를 가지는 변수에다가 같은 데이터를 넣는 것입니다.

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

id(a)
> 1432011675080

id(b)
> 1432011673864

a == b
> True

a is b
> False

b[0] = 10
b
> [10,2,3]

a
> [1,2,3]

살펴보면 ab의 값은 같지만 ab라는 건 아닙니다. 또한 b의 값을 바꿨을 때 a에 영향을 받지 않는 걸 볼 수 있습니다.




12) 리스트 컴프리헨션


리스트를 선언할 때 아래와 같이 선언합니다.

a = [] or a = list()

sq = []

for x in range(10):
    sq.append(x**2)

sq
>[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

그러나 만약에 엄청 큰 숫자의 배열을 리스트에 담을 때는 하나하나 담거나 반복문(for,while)을 사용하여 포함시킵니다. 이를 좀 더 간편하게 해주는 python 기능이 있는데 이를 컴프리헨션이라고 합니다.


sq = [x**2 for x in range(10)] or sq = list(map(lambda x: x**2, range(10)))

좀 더 발전시켜서 반복문과 조건문(if)을 사용하여 만들수도 있습니다.


[(x,y) for x in [1,2,3] for y in [4,5,6] if x != y ]
>[(1, 4), (1, 5), (1, 6), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6)]

12-1) 중첩 컴프리헨션


행렬을 전치할 때 중첩된 컴프리헨션을 사용하는 예를 살펴보겠습니다.

matrix = [
    [1,2,3,4],
    [5,6,7,8],
    [9,10,11,12]
]

[[row[i] for row in matrix] for i in range(4)]
>[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

이렇게 컴프리헨션에 적응하면 적은 코드수로 동일한 효과를 낼 수 있기 때문에 연습하면 유용합니다.




지금까지 리스트, 배열의 기본적인 기능을 알아봤습니다.
리스트를 활용하여 여러 자료구조를 구현할 수 있습니다. 다음 시간에는 리스트를 활용하여 스택(stack)과 큐(queue) 자료구조를 구현해봅시다.


많이 딱딱할 수 있지만, 이 문법들을 가지고 어떤 기능들을 수행할 수 있는 도구로 사용한다면 정말 아름답고 흥미롭게 공부하실 수 있습니다. 긴 글 읽어주셔서 감사드립니다. 😆


참고 :

  • 점프 투 파이썬 (리스트부분)
  • 패스트캠프 강의자료
  • Python 공식 document
  • 파이썬 - 기본을 갈고 닦자!

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함