IDL/Data Type & Format

새로운 Data Type인 리스트(List)에 관하여 [1]

이상우_idl 2011. 5. 6. 18:24
728x90
반응형

IDL 8.0부터 새롭게 도입된 자료형(Data Type)인 리스트(list)와 해쉬(hash)에 관하여 순차적으로 소개하려 합니다. 오늘은 첫번째 순서로 리스트(list)에 관하여 알아보기로 하겠습니다. 이 리스트(list)라는 자료형은 일종의 복합적인 성격을 띄고 있다는 측면에서 구조체(structure)와 유사한 면이 있습니다. 하지만 구조체에 비해서는 훨씬 유연합니다. 먼저 리스트의 전반적인 특성들을 보면 다음과 같습니다.


1. 리스트내의 원소들은 순서에 따라 정렬되어 있으며, 1차원적인 인덱스를 갖는다.

2. 리스트의 원소들은 나중에도 추가 및 삭제가 가능하므로, 리스트의 크기는 항상 유연하게 변할 수 있다.

3. 리스트내의 원소들 자체도 그 값이나 자료형이 언제나 변경 가능하며, 이에 따른 퍼포먼스상의 손해는 전혀 없다.


리스트를 생성하려면 LIST라는 함수를 사용하면 됩니다. 리스트내의 원소들은 어떤 자료형이든 가능하며, 단일값 또는 배열이든 상관이 없습니다. 심지어 구조체나 포인터도 원소가 될 수 있습니다. 다음은 원소의 갯수가 7인 리스트를 임의로 생성해본 것입니다.


IDL> list = LIST('IDL', 5.0, 8, 22, PTR_NEW(10), {a:10.2, b:6}, COMPLEX(4, 3))

IDL> PRINT, N_ELEMENTS(list)

7


다음과 같이 배열들로 구성된 리스트도 생성할 수 있습니다.


IDL> array1 = [4, 5, 6, 7, 8]

IDL> array2 = [2.1, 3.8, 5.2, 6.3]

IDL> list1 = LIST(array1, array2)

IDL> PRINT, N_ELEMENTS(list1)

2


물론 배열 자체가 구성원소이기 때문에 리스트의 원소갯수는 2라고 나옵니다. 그런데 다음과 같이 /EXTRACT 키워드를 사용할 경우에는, 각 배열의 모든 원소들을 추출하여 리스트의 개별 원소들로 만들어버립니다.


IDL> list2 = LIST(array1, array2, /EXTRACT)

IDL> PRINT, N_ELEMENTS(list2)

9


LIST 함수로 생성된 리스트는 마치 객체의 경우와 마찬가지로, 적용가능한 메서드들이 몇가지 존재합니다. 먼저 Add라는 메서드를 사용하면 리스트에 대하여 구성원소를 추가할 수 있습니다. 다음 예제를 봅시다.


IDL> list = LIST(2, 3, 4, 5)

IDL> list.Add, 6

IDL> PRINT, list

2  3  4  5  6 (실제 IDL 인터페이스상에서는 세로 방향으로 출력될겁니다)


이와 같이 구성원소를 추가하면 기본적으로 맨 끝 부분에 추가됩니다. 물론 인덱스를 지정하여 그 부분에 삽입할 수도 있습니다. 다음은 이 리스트에 100이라는 값을 두번째 구성원소로 삽입하는 경우입니다.


IDL> list.Add, 100, 1

IDL> PRINT, list

2  100  3  4  5  6


배열도 물론 중간에 삽입 가능합니다. 배열을 삽입할 경우에 /EXTRACT 키워드를 사용한다면 그 배열의 각 원소들이 리스트의 개별 원소들로서 삽입됩니다. 물론 /EXTRACT를 사용하지 않으면 그냥 배열 자체만 하나의 추가 원소로 삽입됩니다.


IDL> list.Add, [4.3, 4.4, 4.5], 2, /EXTRACT

IDL> PRINT, list

2  100  4.3000  4.4000  4.5000  3  4  5  6


Remove라는 메서드를 사용하여 리스트내의 특정 위치의 원소들을 삭제할 수도 있습니다.


IDL> list = LIST(30.4, 'IDL', [1, 2, 3], ['aa', 'bb'])

IDL> list.Remove, 2

IDL> PRINT, list

30.4000

IDL

aa  bb


여기서는 4개의 구성원소들로 이루어진 리스트에 대하여 3번째 원소를 제거하였습니다. 따라서 이 위치에 해당되는 [1, 2, 3]이라는 배열이 삭제된 것입니다. 그리고 Remove 메서드를 다음과 같이 함수의 형태처럼 사용하면, 삭제의 대상이 된 원소를 따로 추출할 수도 있습니다. 물론 이 경우에도 해당 원소에 대한 삭제도 동시에 이루어진다는 점을 유의해야 합니다.


IDL> xx = list.Remove(0)

IDL> PRINT, xx

30.4000

IDL> PRINT, N_ELEMENTS(list)

2


참고로 인덱스를 전혀 주지않고 Remove 메서드를 사용하면, 리스트의 맨 끝에 위치한 원소가 제거됩니다.


IDL> list.Remove 또는 IDL> xx = list.Remove()

IDL> PRINT, N_ELEMENTS(list)

1


Reverse 메서드는 말 그대로 리스트의 원소들의 순서를 역순으로 재배치하는 역할을 합니다.


IDL> list = LIST(1, 2, 3, 4)

IDL> list.Reverse

IDL> PRINT, list

4  3  2  1


ToArray 메서드는 리스트의 원소들로 이루어진 배열을 전달하는 역할을 합니다. 다음 예제를 봅시다.


IDL> list = LIST(5, '87', 4.26, COMPLEX(2))

IDL> arr = list.ToArray()

IDL> HELP, arr

ARR   INT   =   Array[4]

IDL> PRINT, arr

5  87  4  2


이 메서드를 사용하여 배열을 생성할 경우 이 배열의 자료형은 기본적으로 리스트내의 맨 첫번째 원소의 형을 따릅니다. 따라서 이와 같이 정수형의 배열로 생성된 것입니다. 이 경우 리스트내에서 정수형이 아니었던 원소들도 강제로 정수형으로 변환됩니다. 물론 변환시의 자료형은 임의로 명시할 수도 있습니다. 예를 들면 다음과 같이 실수형으로 지정할 수도 있겠죠.


IDL> arr = list.ToArray(TYPE='Float')

IDL> HELP, arr

ARR   FLOAT   =   Array[4]

IDL> PRINT, arr

5.00000  87.0000  4.20000  2.00000


그리고 다음과 같이 리스트내에 문자열이 구성원소로 들어가 있는 상태에서, 이 리스트를 정수형 배열로 변환할 경우를 생각해봅시다.


IDL> list = LIST(5, '87', 4.26, 'Ooops', COMPLEX(2))

IDL> arr = list.ToArray()


이와 같이 그냥 ToArray 메서드를 사용하면 에러가 납니다. 중간에 있는 문자열인 'Ooops'를 정수로 변환할 수 없기 때문입니다. 이와 같은 경우에는 MISSING이라는 키워드를 사용하여, 변환이 애초에 불가능한 값을 어떤 값으로 대체할 것인가를 정해주면 됩니다.


IDL> arr = list.ToArray(MISSING=-999)

IDL> PRINT, arr

5  87  4  -999 2


여기까지 리스트에 관한 기본적인 내용을 살펴보았습니다. 내용이 좀 더 남았는데 너무 길어질 것 같아서 다음 기회에 마저 이어서 올리도록 하겠습니다.


* 이 글은 idluser.org 사이트의 IDL Tip 게시판의 118번 게시물로도 보실 수 있습니다.

반응형