본문 바로가기
Development/Algorithms

algorithms/배열(array)

by dohk325 2019. 12. 30.
반응형

                                                                                                                                                         

                                                                                                                                                                                                                   

                                                                                                                                                         

                                                                                                                                                                                                              

                                                                                                                                                                     

배열이란, 데이터 하나하나를 인덱스(index)에 대응시킨 데이터 구조다. 이 때, 배열에 저장되는 데이터들은 동일한 종류의 데이터들이 저장된다. 인덱스에 따라 데이터가 순차적으로 나열된다는 특징이 있으며, 인덱스를 이용해 곧바로 데이터에 접근할 수 있다. 순서가 중요한 데이터를 배열에 담는 것이 유용할 것이다. 순서가 중요한 데이터의 대표는 string이다. ‘computer’라는 단어를 배열에 저장한다고 할 때, c-o-m-p-u-t-e-r의 순서로 저장되는 것이 옳다. 이럴 경우 배열이 적합하다. 각각의 배열 요소에는 인덱스가 붙는데, c는 인덱스 0, o는 인덱스 1과 같은 식으로 인덱스가 부여된다. 파이썬에서는 list가 배열로서 기능한다.

파이썬의 list는 배열 자료구조 그 자체라고 보기는 어렵다. 배열 외에도 편리한 기능들을 더 많이 담고 있기 때문이다. 예를 들면, 배열의 본래 필요성은 같은 종류의 데이터들을 저장하기 위한 용도이지만, 파이썬의 list는 다른 종류의 데이터들, 서로 다른 타입의 데이터들도 함께 담아낼 수 있다.

 

배열의 장점

  • 빠른 접근이 가능

    인덱스 번호만으로 데이터에 빠르게 접근할 수 있다. ‘computer’를 담은 배열을 예로 들면, 인덱스 0인 ‘c’에서 7번째의 데이터에 접근하면 곧바로 ‘r’에 접근할 수 있다.

배열의 단점

  • 크기 제한으로 인해 데이터의 추가, 삭제가 쉽지 않다.

    ‘computer’라는 글자를 저장하기 위해 배열의 크기가 7이어야 한다는 것을 알아야하고, 한 번 설정한 이 크기는 더이상 변경할 수 없어서 더 이상의 글자를 추가할 수 없다. 따라서, 이런 경우에는 별도의 배열을 만들어줘야 한다.

    또한, 한 번 설정된 크기를 변경할 수 없기 때문에 ‘computer'에서 ‘r’을 제외한 ‘compute_’라는 글자만을 저장하고자 할 때, 공간의 낭비가 발생한다.

    또한, ‘computer’에서 모음들만을 제거한다고 할 때(‘cmptr’), 모음을 제거함으로써 생긴 빈 공간들을 채워줘야만 한다. ‘computer’ —> ’c_mp_t_r’ —> ‘cmptr'

배열의 코드 예

  • C

 

 

배열의 사이즈가 5로 정해진 것을 확인할 수 있다. c언어에서는 배열에 문자를 담기 위해서는, 문자의 마지막을 알리는 Null까지 고려하여 원래 글자수에 한 개가 더해진 만큼의 크기가 정해져야 한다.

  • Python

 

 

kwon 
<class 'str’> 
kwon 
kwon

 

타입은 파이썬에서 문자열을 의미하는 ’str’이지만, 배열처럼 접근 가능한 것을 확인할 수 있다. 하지만 파이썬에서는 문자열의 길이를 미리 지정해놓지 않아도 저장되는 것을 알 수 있다. 따라서, 아래 예시와 같이 크기 제한에 따른 데이터 추가, 제거에 제한이 없다.

 

 

 

kwon do

 

파이썬에서는 list라는 내장함수를 통해 str타입의 자료구조를 파이썬의 list로 저장할 수 있다. 배열 요소로의 접근은 str과 동일한 것을 확인할 수 있다.

파이썬에서는 오로지 str타입의 변수만이 배열스러우며, 그 외에 숫자나 다른 자료를 저장할 경우에는 배열과 같은 기능은 하지 않는다. 아래 예시를 보자.

 

 

 

---------------------------------------------------------------------------

TypeError Traceback (most recent call last)

<ipython-input-13-a6b19f3be43b> in <module>

**1** number = 12345

----> 2 print(number[0])

TypeError: 'int' object is not subscriptable

TypeError가 난 것을 볼 수 있다. 변수 name에 했던 것처럼, 변수 number에 대입연산자를 통해 str 타입이 아닌 int 타입의 데이터를 저장했더니, int 객체로는 인덱스 접근이 불가능하다는 에러가 나온다.

 

 

---------------------------------------------------------------------------

TypeError Traceback (most recent call last)

<ipython-input-15-79dedd054933> in <module>

----> 1 number = list(12345)

**2** print(len(number))

**3** for i in range(len(number)):

**4** print("{}".format(number[i]), end="")

TypeError: 'int' object is not iterable

숫자를 리스트로 만들어주기 위해서는 위와 같이 해서는 안된다. list의 파라미터로는 iterable한 객체가 들어가야 하기 때문이다. 숫자는 그 자체로 하나의 데이터이기 때문에 iterable객체가 아니다. 따라서 아래 예시와 같이 숫자를 문자열로 만들어준 다음 배열로 저장해야 한다.

 

 

12345

파이썬 list 활용

  • 1차원 배열 구현

    파이썬에서 배열을 구현하는 방법엔 여러가지가 있다.

 

 

['1', '2', '3', '4', '5']
5
12345

 

 

 

[1, 2, 3, 4, 5]
5
12345

 

 

 

12345
12345
['1', '2', '3', '4', '5']
12345

 

 

 

[1, 2, 3, 4, 5]
12345

 

  • 2차원 배열

 

 

print를 이용한 출력
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
for문을 이용한 출력 1
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
for문을 이용한 출력 2
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
for문을 이용한 출력 3
1, 2, 3
4, 5, 6
7, 8, 9
for문을 이용한 출력 4
1, 2, 3
4, 5, 6
7, 8, 9

예제

  • 주어진 데이터셋에서 알파벳 K 또는 k가 들어있는 단어의 개수를 세자.

 

 

먼저, 데이터셋은 https://catalog.data.gov/dataset/baby-names-from-social-security-card-applications-territory-data/resource/8dbd67a5-f146-435c-ad34-3ee10ae61902 에서 얻었다. zip파일이 주어지며, 이름을 제외한 불필요한 정보들은 메모장에서 텍스트 대치기능으로 지웠다.

그 다음, 파일을 파이썬을 이용하여 오픈하여 읽어들인다.

 

 

<class 'str'>
['Paola,', 'Genesis,', 'Gabriela,', 'Nicole,', 'Alondra,', 'Maria,', 'Nashaly,', 'Stephanie,', 'Andrea,', 'Adriana,']
1195
['Paola', 'Genesis', 'Gabriela', 'Nicole', 'Alondra', 'Maria', 'Nashaly', 'Stephanie', 'Andrea', 'Adriana’]

읽어들인 데이터의 타입을 확인해보니 str이다. 이를 str 객체에 있는 메서드인 split을 이용하여 특정 문자열을 기준으로 나누어, list 객체로 만들어준다. 이 객체의 이름을 name으로 한다.

나누어진 모습을 보니, 제거해야 할 문자(‘,’)가 보인다. 이 문자를 제거하기 위해 str 객체의 메서드인 replace를 이용하여 제거한다. replace는 대체할 대상이 되는 문자와 어떤 문자로 대체할지를 파라미터로 넘기면 되는데, 여기서는 그냥 제거하기 위하여 빈 문자열(“”)을 대체할 문자로 넣는다.

 

 

그 다음, K 또는 k가 들어있는 단어의 개수를 세기 위한 변수와 이 단어들을 리스트로 저장하기 위한 변수를 선언한 후, list 타입인 name 변수 속에 K나 k가 있는지를 조건문으로 확인 후, 단어를 세어나가면 끝이다.

만약, 단어의 개수가 아니라 K나 k 글자 자체의 개수를 알고 싶다면?

 

 

['Karla', 'Kimberly', 'Kiara', 'Karina', 'Krystal', 'Keishla', 'Shakira', 'Keyshla', 'Ninoshka', 'Katherine']
117
118

요소 하나하나에 대한 인덱스를 검사하여 글자의 개수를 세는 방식으로 변경해야 한다. 하지만 알파벳 K의 특성 상, 하나의 이름에 하나의 K가 들어가는 경우가 많아 개수 구분이 유의미해 보이지 않는다. 따라서 아래 코드와 같이 모음으로 다시 실험해보았다.

 

 

['Genesis', 'Gabriela', 'Nicole', 'Stephanie', 'Andrea', 'Valeria', 'Alexandra', 'Melanie', 'Angelica', 'Ashley']
632
802

알파벳의 이름을 매번 수정해주기 귀찮으므로 함수화 시킨다.

 

 

 

 

<class 'str'>
['Paola,', 'Genesis,', 'Gabriela,', 'Nicole,', 'Alondra,', 'Maria,', 'Nashaly,', 'Stephanie,', 'Andrea,', 'Adriana,']
1195
['Genesis,', 'Gabriela,', 'Nicole,', 'Stephanie,', 'Andrea,', 'Valeria,', 'Alexandra,', 'Melanie,', 'Angelica,', 'Ashley,']
632
802

Reference

반응형