Python에서 객체에 대한 key, value 조회

key, value 자료 구조는 매우 효율적인으로 데이터를 저장하고 빠르게 검색할 수 있는 구조입니다. Python에서도 제공하는 key, value 자료구조는 Javascript와 매우 유사한데요. 예를들어 다음처럼 key와 value를 자유롭게 구성할 수 있습니다.

book = {
    'Boy': (100, 200),
    'Guy': (200, 400),
    'Girl': (300, 150),
    'Woman': (400, 800)
}

총 4개의 요소로 구성되어 있는데.. 각 요소를 순회하면서 조회하기 위한 코드는 다음과 같습니다.

for word, pages in book.items():
    print(word, pages)

위의 실행 결과는 다음과 같습니다.

Boy (100, 200)
Guy (200, 400)
Girl (300, 150)
Woman (400, 800)

앞서 book 변수에 대한 타입명은 dictionary입니다. 이 타입에서 key 요소는 중복될 수 없습니다.

특정 key 값을 갖는 요소를 제거하기 위해서는, 예를들어 key가 ‘Boy’ 인 요소를 제거하기 위한 코드는 다음과 같습니다.

del book['Boy']

또한 특정 키를 가진 요소가 존재하는지에 대한 검사는 다음과 같습니다.

print('Boy' in book)
print('Girl' in book)

앞서 key가 ‘Boy’인 요소는 제거되었으므로, 위의 코드에 대한 결과는 다음과 같습니다.

False
True

처리해야 할 공백 문자가 있다면, 꼭 고려해야 할 ‘ZERO WIDTH SPACE’

Code 값 32는 가장 흔히 볼 수 볼 수 있는 공백문자. 160도 공백문자인데, nbsp(Non-breaking Space) 문자라고 한다. 여기에 하나더 Code 값 8203이 있는데 이 값 역시 공백문자이다. 그런데 공백을 차지 하지 않는 공백문자, ‘ZERO WIDTH SPACE’라고 한단다. 보이지 않는 공백문자, 다른 말로 공백이 아닌 공백 문자이다. 참고로 유니코드 문자셋이다.

아래의 코드는 Javascript에서 Space 문자를 제거하는 코드이다.

let address = '공백 문자를 포함하는 문장';
let arrAddress = [];
for (let i = 0; i < address.length; i++) {
    let charCode = address.charCodeAt(i);
    if (charCode === 8203 /* Unicode Character 'ZERO WIDTH SPACE' */ || 
        charCode === 160 /* nbsp(non-breaking space) */ || 
        charCode === 32 /* Space */) {
        // skips all space chars
    } else {
        arrAddress.push(address[i]);
    }
}
address = arrAddress.join("");

이 글에서 언급하는 Space 문자로 3개 언급했는데.. 또 있다면 코드에 반영해야 할 것이다. 참고로 Javascript에서 문자열의 실행중 변경은 배열을 사용해야 한다. 즉, Java의 StringBuilder의 용도와 동일하다.

DBMS에서 ST_EXTENT 함수를 제공하지 않을 경우의 대안

PostgreSQL 등과 같은 공간 DB에서는 ST_EXTENT를 지원하지만, 오라클이나 티베로 등과 같은 DBMS에서는 이 함수를 제공하지 않습니다. 다행이 오라클은 SDO_AGGR_MBR라는 함수를 제공함으로써 ST_EXTENT 대신 사용할 수 있습니다. (최근의 오라클은 ST_EXTENT를 지원할지도 모르겠습니다) 그러나 오라클처럼 자체적인 함수 조차도 지원하지 않는 티베로와 같은 경우 사용할 수 있는 대안은 다음과 같습니다.

SELECT * 
FROM 
    (SELECT * FROM (SELECT ST_MINX(the_geom) MinX FROM TSTTABLE ORDER BY ST_MINX(the_geom) ASC) WHERE ROWNUM = 1 ), 
    (SELECT * FROM (SELECT ST_MAXX(the_geom) MaxX FROM TSTTABLE ORDER BY ST_MAXX(the_geom) DESC) WHERE ROWNUM = 1),
    (SELECT * FROM (SELECT ST_MINY(the_geom) MinY FROM TSTTABLE ORDER BY ST_MINY(the_geom) ASC) WHERE ROWNUM = 1),
    (SELECT * FROM (SELECT ST_MAXY(the_geom) MaxY FROM TSTTABLE ORDER BY ST_MAXY(the_geom) DESC) WHERE ROWNUM = 1);

대상 테이블의 이름은 TSTTABLE이고 Geometry 필드는 the_gem입니다. 결과의 예는 다음과 같습니다.

위의 쿼리는 티베로에서 실행한 결과입니다. 위처럼 하나의 Row로 결과를 얻을 수도 있지만 MinX, MaxX, MinY, MaxY 각각을 하나의 Row로 얻을 수도 있습니다. 아래처럼요.

SELECT * FROM (SELECT ST_MINX(the_geom) FROM TSTTABLE  ORDER BY ST_MINX(the_geom) ASC) WHERE ROWNUM = 1 
UNION SELECT * FROM (SELECT ST_MAXX(the_geom) FROM TSTTABLE  ORDER BY ST_MAXX(the_geom) DESC) WHERE ROWNUM = 1
UNION SELECT * FROM (SELECT ST_MINY(the_geom) FROM TSTTABLE  ORDER BY ST_MINY(the_geom) ASC) WHERE ROWNUM = 1
UNION SELECT * FROM (SELECT ST_MAXY(the_geom) FROM TSTTABLE  ORDER BY ST_MAXY(the_geom) DESC) WHERE ROWNUM = 1;

참고로 이 대안들은 속도가 느립니다. 테이블에 데이터가 개수가 많을 수록 그 속도는 더욱 느려집니다. 그러므로 해당 DBMS에서 ST_EXTENT를 제공한다면, ST_EXTENT를 사용해야 하며 ST_EXTENT를 지원하지 않는다면 해당 DBMS에서 자체적인 방법을 제공하는지 확인하여 그 방법을 사용해야 합니다. 자체적인 방법까지도 없다면 위의 대안을 사용할 수 있습니다.