IDL/Data Type & Format

리스트(List) 자료형에 관하여 [1]

이상우_IDL 2025. 6. 4. 15:47
728x90

리스트(List)와 해쉬(Hash)IDL 8.0 버전에서부터 지원되기 시작한 자료형(Data Type)들입니다. 이 두 자료형들은 기존의 정수, 실수, 문자 등과 같은 단일형 자료형과는 다른 일종의 복합형 자료형의 성격을 띕니다. 즉 서로 다른 자료형의 값들을 한꺼번에 품을 수 있는 특성을 갖는다고 보면 됩니다. IDL 8.0 버전 이전에는 구조체(Structre)만이 이러한 복합형 자료형의 범주에 속했지만, 그 이후부터는 리스트와 해쉬 자료형들까지 추가되면서 IDL에서 활용 가능한 복합형 자료형들의 범위가 더 넓어졌다고 볼 수 있습니다. 그래서 리스트 및 해쉬 자료형에 관하여 순차적으로 소개해보고자 합니다.

 

오늘은 첫번째 순서로 리스트(List) 자료형에 관하여 알아보기로 하겠습니다. 리스트 자료형은 앞서 언급했듯이 복합형 자료형의 성격을 띄고 있다는 측면에서 구조체(structure)와 유사한 면이 있지만, 구조체에 비해서는 훨씬 유연한 활용이 가능합니다. 먼저 리스트의 전반적인 특성들을 보면 다음과 같습니다.

 

1. 리스트 개체 내의 원소들은 순서에 따라 정렬되어 있으며, 마치 1차원 배열과 같은 구조를 갖는다.

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

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

 

리스트 개체를 생성하려면 LIST 함수를 사용하면 됩니다. 리스트 내의 원소들은 어떤 자료형이든 가능할 뿐 아니라 단일값 또는 배열이 되든 상관이 없습니다. 심지어 구조체(Structure), 포인터(Pointer) 및 다른 리스트 개체도 리스트 내 원소가 될 수 있습니다. 예를 들어서 다음과 같이 원소의 갯수가 7인 리스트 개체를 하나 생성해봅시다.

 

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

IDL> PRINT, N_ELEMENTS(lst)

7

 

여기서는 lst라는 이름의 리스트 개체를 생성하고 그 원소 갯수가 7임을 확인해본 것입니다. 이와 같이 리스트 개체를 새롭게 생성하려면 이를 구성할 원소들을 LIST 함수 내에 순서대로 투입하면 됩니다. 위의 예제를 보면 리스트 개체 내 원소들이 정수, 실수, 문자, 포인터, 구조체, 복소수 등 다양한 자료형의 값들로 구성된 것을 볼 수 있습니다. 이번에는 다음과 같이 배열들로만 구성된 리스트 개체인 lst1을 생성해봅시다.

 

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

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

IDL> lst1 = LIST(array1, array2)

IDL> PRINT, N_ELEMENTS(lst1)

2

 

물론 이 리스트 개체의 구성 원소는 두 개의 배열들이기 때문에 그 원소갯수는 2로 확인됩니다. 그런데 다음과 같이 LIST 함수를 /EXTRACT 키워드와 함께 사용할 경우에는 각 배열을 개별 원소로 취급하는 대신 각 배열의 원소값들을 모두 추출하고 하나로 합쳐서 이 값들로 구성되는 리스트 개체를 얻게 됩니다. 다음은 이러한 방식으로 lst2라는 리스트 개체를 얻는 경우입니다.

 

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

IDL> PRINT, N_ELEMENTS(lst2)

9

 

이와 같이 기존의 두 배열(array1, array2)의 원소값 갯수가 각각 5, 4였으므로 이 값들이 합쳐져서 구성된 새로운 리스트인 lst2는 9개의 값들로 구성된 리스트 개체가 됩니다.

 

이번에는 LIST 함수로 생성된 리스트 개체에 대하여 여러가지 작업들을 할 수 있도록 해주는 메서드들(Methods)에 관하여 알아봅시다.

 

< 새로운 구성 원소의 추가 >

 

먼저 Add 메서드를 사용하면 리스트 개체에 대하여 새로운 구성원소를 추가할 수 있습니다. 다음 예제를 봅시다.

 

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

IDL> lst.Add, 6

IDL> PRINT, lst

       2
       3
       4
       5
       6

 

이와 같이 리스트 개체에 대하여 새로운 구성원소를 추가하면 기본적으로 맨 끝 부분에 추가됩니다. 물론 인덱스를 지정하여 특정한 위치에 삽입할 수도 있습니다. 다음은 위의 리스트 개체 lst에 100이라는 값을 두번째 구성원소로 삽입하는 경우입니다. 두번째라는 위치를 뜻하는 인덱스 1을 Add 메서드의 추가 인자로 사용하면 됩니다.

 

IDL> lst.Add, 100, 1

IDL> PRINT, lst

2  100  3  4  5  6

 

중간에 삽입될 새로운 구성원소가 단일값이 아닌 배열이 될 수도 있습니다. 배열을 삽입할 경우에 /EXTRACT 키워드를 사용한다면 그 배열의 모든 원소값들이 리스트 개체의 개별 원소들로서 삽입됩니다.

 

IDL> lst = LIST(2, 3, 4, 5)
IDL> lst.Add, [10, 11, 12], 2, /EXTRACT
IDL> PRINT, lst
       2
       3
      10
      11
      12
       4
       5

 

하지만 /EXTRACT 키워드를 사용하지 않을 경우에는 그냥 배열 자체가 리스트 개체의 하나의 추가 원소로 삽입됩니다.

 

IDL> lst = LIST(2, 3, 4, 5)
IDL> lst.Add, [10, 11, 12], 2
IDL> PRINT, lst
       2
       3
      10      11      12
       4
       5

 

< 기존 구성 원소의 삭제 >

 

Remove 메서드는 리스트 개체 내의 특정 위치의 원소들을 삭제하는 역할을 합니다. 삭제할 대상의 위치에 해당되는 인덱스를 인수로 부여하면 됩니다.

 

IDL> lst = LIST(30.4, 'hello', [1, 2, 3], ['aa', 'bb'], 5, 8)
IDL> lst.Remove, 2
IDL> PRINT, lst
       30.400000
hello
aabb
       5
       8

 

여기서는 6개의 구성원소들로 이루어진 리스트에 대하여 3번째 원소를 제거한 것입니다. 따라서 이 위치에 해당되는 [1, 2, 3]이라는 배열이 삭제되었습니다. 만약 삭제할 대상이 다수일 경우에는 해당 인덱스들로 구성된 배열을 인자로 주면 됩니다.

 

IDL> lst = LIST(30.4, 'hello', [1, 2, 3], ['aa', 'bb'], 5, 8)
IDL> lst.Remove, [2:4]
IDL> PRINT, lst
       30.400000
hello
       8

 

그리고 Remove 메서드를 다음과 같이 함수의 형태처럼 사용하면, 삭제의 대상이 된 원소를 따로 추출할 수도 있습니다. 물론 이 경우 해당 원소에 대한 삭제도 동시에 수행된다는 점을 유의해야 합니다.

 

IDL> lst = LIST(30.4, 'hello', [1, 2, 3], ['aa', 'bb'], 5, 8)
IDL> xx = lst.Remove(0)
IDL> PRINT, xx
      30.4000

IDL> PRINT, lst
hello
       1       2       3
aabb
       5
       8

 

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

 

IDL> lst = LIST(30.4, 'hello', [1, 2, 3], ['aa', 'bb'], 5, 8)
IDL> lst.Remove()
       8
IDL> PRINT, lst
       30.400000
hello
       1       2       3
aabb
       5

 

< 구성 원소들의 순서 뒤집기 >

 

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

 

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

IDL> lst.Reverse

IDL> PRINT, lst

4  3  2  1

 

< 구성 원소들을 배열로 추출 >

 

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

 

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

IDL> arr = lst.ToArray()

IDL> HELP, arr

ARR   INT   =   Array[4]

IDL> PRINT, arr

5  87  4  2

 

이 메서드를 사용하여 얻게 되는 배열의 자료형은 리스트 개체 내의 맨 첫번째 원소의 자료형을 따르는 것이 디폴트입니다. 위의 예제에서 arr이 정수형 배열로 얻어진 것이 바로 그러한 이유 때문입니다. 다만 이런 상황에서는 리스트 개체 내에서 정수형이 아니었던 원소들도 강제로 정수형으로 변환된다는 것을 유의해야 합니다. 물론 변환시의 자료형은 직접 지정할 수도 있습니다. 예를 들면 다음과 같이 실수형으로 지정하는 것도 가능합니다.

 

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

IDL> HELP, arr

ARR   FLOAT   =   Array[4]

IDL> PRINT, arr

5.00000  87.0000  4.20000  2.00000

 

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

 

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

IDL> arr = lst.ToArray()

 

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

 

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

IDL> PRINT, arr

5  87  4  -999 2

 

지금까지 리스트(List) 자료형에 관한 기본적인 내용을 여러가지 예제들과 함께 살펴보았습니다. 리스트 자료형에 관한 나머지 내용은 다음 회차 게시물에서 마저 이어나가도록 하겠습니다.

 

 

* 이 내용은 지난 2011년에 올렸던 게시물의 내용을 일부 수정하여 다시 새롭게 올리는 내용입니다. 따라서 기존의 게시물은 이번 내용으로 대체되었습니다.

 

* 이 글이 도움이 되었다면 게시물에 대하여 공감 버튼(하트 모양) 클릭 및 블로그 구독도 해주시면 더 큰 힘이 됩니다. 감사합니다.

 

LIST