[Python] 정렬, 문자열비교, enumerate

2 분 소요

리스트의 sort 메소드

>>> ns = [3,1,4,2]
>>> ns.sort()  # 기본 오름차순
>>> ns
[1,2,3,4]

리스트에는 sort메소드가 제공된다. sort가 호출되면, 이 메소드는 내부적으로 모든 값들을 대상으로 연산을 진행하고(어느 값이 어느 위치에 있어야 하는지 판단하기 위해서) 그 결과를 바탕으로 오름차순 정렬을 한다.

>>> ns = [3,1,4,2]
>>> ns.sort(reverse=True)  # 내림차순 정렬을 위한 True 전달
>>> ns
[4,3,2,1]

내림차순은 매개변수 reverse에 True를 전달하면 된다.

>>> ns = [('Yoon',33), ('Lee',12), ('Park',29)]
>>> def age(t):
        return t[1]

>>> ns.sort(key=age)
>>> ns
[('Lee',12), ('Park',29), ('Yoon',33)]

위 코드처럼 이름과 나이 정보가 묶여 있는 경우 나이를 반환하는 함수를 만들어 정렬하면 된다.

>>> ns.sort(key=age, reverse=True)

만약 나이를 기준으로 내림차순 정렬을 하고 싶다면 다음과 같이 하면 된다.

>>> ns.sort(key=lambda t : t[0], reverse=True)

위 코드는 람다식을 이용해 이름의 알파벳 역순으로 정렬하는 코드이다.

>>> names = ['julia', 'yoon', 'steven']
>>> names.sort(key=len)
>>> names
['yoon', 'julia', 'steven']

리스트를 대상으로 문자열의 길이로 오름차순 정렬을 하고싶다면 key에 len함수를 전달하면 된다.

>>> nums = [(3,1). (2,9), (0,5)]
>>> nums.sort(key=lambda t : t[0]+t[1], reverse=True)
>>> nums
[(2,9), (0,5), (3,1)]

위 코드는 람다식을 기반으로 튜플을 이루는 두 수의 합이고 내림차순 정렬을 한다.



sorted 함수

sort 메소드를 사용하면 리스트 자체를 수정한다. 원본을 유지하고 정렬된 사본을 얻고 싶은 경우 sorted함수를 사용하면 된다. 사용방법은 sort함수와 동일하다. 첫번째 값으로 정렬 대상을 전달해 주는 부분에서만 차이가 있다.

>>> org = [('Yoon',33), ('Lee',12), ('Park',29)]
>>> cpy = sorted(org, key=lambda t : t[1], reverse=True)
>>> org
[('Yoon',33), ('Lee',12), ('Park',29)]
>>> cpy
[('Yoon',33), ('Park',29), ('Lee',12)]
>>> org = (3,1,2)
>>> cpy = sorted(org)  # cpy = tuple(sorted(org)) : 원본과 동일한 자료형을 유지해야 한다면...
>>> org
(3,1,2)
>>> cpy
[1,2,3]

튜플은 내용을 수정할 수 없기때문에 sort메소드가 존재하지 않는다. 하지만 sorted함수는 정렬된 사본을 새로 생성하기 때문에 iterable 객체면 무엇이든 전달할 수 있다. 정렬 결과는 리스트에 담아서 반환된다.

>>> org = ('321', '214', '197')
>>> cpy = tuple(sorted(org, key=lambda s : int(s[0])))
>>> cpy
('197', '214', '321')

위 코드는 튜플을 대상으로 sorted함수를 호출해 정렬된 튜플을 얻는 예이다. 정렬 기준은 문자열의 첫번째 숫자로 오른차순 했다.



문자열 비교

>>> 'A' < 'Z'
True
>>> 'AA' < 'AZ'
True
>>> 'AA' < 'AAA'
True
>>> 'A' < 'a'
True

알파벳 순서상 뒤로 갈수록 크고, 첫번재 문자가 같다면 두번째 문자를 비교한다. 비교하는 문자들이 모두 같다면, 하나라도 긴 문자열이 크고, 소문자가 대문자보다 크다.

>>> '가' < '나'
True
>>> '가' < '구'
True
>>> '가가' < '가나'
True
>>> '하하' < '하하하'
True

한글의 경우 가나다순으로 뒤로 갈수록 크고, 아야어여오요우유으이 순으로 뒤로 갈수록 크다. 첫번째 문자가 같다면 두 번째 문자를 비교한다. 비교하는 문자들이 모두 같다면 하나라도 긴 문자열이 크다.



enumerate

enumerate 함수는 ‘enumerate 객체라는 iterator 객체를 생성한다.

>>> names = ['윤나은','김현주','장현지','이지선','박선주']
>>> eo = enumerate(names)
>>> for n in eo:
        print(n)

(0, '윤나은')
(1, '김현주')
(2, '장현지')
(3, '이지선')
(4, '박선주')

enumerate 함수는 리스트와 같은 iterable 객체를 인자로 전달받는다. 그러면 전달된 리스트에 있는 값들을 하나씩 반환해주는데(enumerate 함수가 반환하는 iterator 객체를 통해서) 0부터 번호를 매겨서 튜플에 감싸서 반환을 한다.

>>> names = ['윤나은','김현주','장현지','이지선','박선주']
>>> eo = enumerate(names,10)
>>> for n in eo:
        print(n)

(10, '윤나은')
(11, '김현주')
(12, '장현지')
(13, '이지선')
(14, '박선주')

만약 번호를 10부터 매기고자 한다면 다음과 같이 그 값을 두번째 인자로 전달하면 된다.

>>> names = ['윤나은','김현주','장현지','이지선','박선주']
>>> dnames = {k: v for k,v in enumerate(sorted(names), 1)}
{1: '김현주', 2: '박선주', 3: '윤나은', 4: '이지선', 5: '장현지'}

다음과 같이 딕셔너리 컴프리헨션과 enumerate함수를 같이 사용할 수 있다.