[파이썬3.0] 데이터 정렬
프로그램 언어/파이썬2014. 6. 24. 22:25
데이터 정렬
우리가 사는 사회는 정렬을 좋아한다.
데이터도 다르지 않다.
그러나 데이터를 입력할 때 정렬된 형태로 입력하지는 않는다.
비정돈된 데이터를 불러와서 정렬작업을 하여 원하는 결과를 도출해야 한다
이번에는 바로 그 정렬을 하는 것을 해보자.
with open('james.txt') as 제임스파일:
data=제임스파일.readline()
제임스 = data.strip().split(',')
with open('julie.txt') as 줄리파일:
data=줄리파일.readline()
줄리 = data.strip().split(',')
with open('mikey.txt') as 미키파일:
data=미키파일.readline()
미키 = data.strip().split(',')
with open('sarah.txt') as 사라파일:
data=사라파일.readline()
사라 = data.strip().split(',')
print(제임스)
print(줄리)
print(미키)
print(사라)
>>>
['2-34', '3:21', '2.34', '2.45', '3.01', '2:01', '2:01', '3:10', '2-22']
['2.59', '2.11', '2:11', '2:23', '3-10', '2-23', '3:10', '3.21', '3-21']
['2:22', '3.01', '3:01', '3.02', '3:02', '3.02', '3:22', '2.49', '2:38']
['2:58', '2.58', '2:39', '2-25', '2-55', '2:54', '2.18', '2:55', '2:55']
['2-34', '3:21', '2.34', '2.45', '3.01', '2:01', '2:01', '3:10', '2-22']
['2.59', '2.11', '2:11', '2:23', '3-10', '2-23', '3:10', '3.21', '3-21']
['2:22', '3.01', '3:01', '3.02', '3:02', '3.02', '3:22', '2.49', '2:38']
['2:58', '2.58', '2:39', '2-25', '2-55', '2:54', '2.18', '2:55', '2:55']
위 데이터는 시 분 단위로 기록되어 있는 시간데이터이다.
보면 정렬이 되지 않았다.
그럼 이제 저 데이터를 정렬된 형태로 출력을 해보자.
먼저 정렬 방법을 알아보자.
-
원본 정렬
-
사본 정렬
이렇게 두가지가 있다.
1. 원본 정렬(In-place-sorting)
데이터를 가져와서 지정한 순서대로 정렬을 하고, 원래의 데이터를 정렬된 데이터로 대체하는 것을 의미한다. 즉 원본 자체가 정렬된 형태로 변경되는 것이다.
사용하는 방법은
리스트의 sort()메서드를 사용하면 된다.
기본적으로 오름차순으로 정렬 reverse=True 를 인자로 주면 내림차순으로 정렬.
2. 사본 정렬(Copied sorting)
데이터를 가져와서 지정한 순서대로 정렬
정렬된 것을 반환한다.
즉, 이 방법은 원본 데이터에는 영향이 없고 말그대로 사본을 만들어서 그 복사된 데이터를 반환시키는 것이다.
사용 방법
sorted() 내장 함수를 이용
기본적으로 오름차순, reverse=True 인자로 내림차순으로 변경가능.
그러나 원본 정렬과 달리 복사하기 때문에 복사한(정렬된) 데이터를 받아줄 객체가 필요하다.
xxxx=sorted(원본) 형태가 된다.
그림으로 표현하여 비교하면,
방금 전 정렬되지 않은 것을 정렬해 해보자.
>>>
['2-34', '3:21', '2.34', '2.45', '3.01', '2:01', '2:01', '3:10', '2-22']
['2.59', '2.11', '2:11', '2:23', '3-10', '2-23', '3:10', '3.21', '3-21']
['2:22', '3.01', '3:01', '3.02', '3:02', '3.02', '3:22', '2.49', '2:38']
['2:58', '2.58', '2:39', '2-25', '2-55', '2:54', '2.18', '2:55', '2:55']
['2-34', '3:21', '2.34', '2.45', '3.01', '2:01', '2:01', '3:10', '2-22']
['2.59', '2.11', '2:11', '2:23', '3-10', '2-23', '3:10', '3.21', '3-21']
['2:22', '3.01', '3:01', '3.02', '3:02', '3.02', '3:22', '2.49', '2:38']
['2:58', '2.58', '2:39', '2-25', '2-55', '2:54', '2.18', '2:55', '2:55']
정렬 전이다.
정렬을 위한 코드
ex_sorting.py
with open('james.txt') as 제임스파일:
data=제임스파일.readline()
제임스 = data.strip().split(',') #메서드 연속 호출(method chaining) 왼쪽에서 부터 오른쪽으로 동작.
with open('julie.txt') as 줄리파일:
data=줄리파일.readline()
줄리 = data.strip().split(',')
with open('mikey.txt') as 미키파일:
data=미키파일.readline()
미키 = data.strip().split(',')
with open('sarah.txt') as 사라파일:
data=사라파일.readline()
사라 = data.strip().split(',')
print(sorted(제임스))
print(sorted(줄리))
print(sorted(미키))
print(sorted(사라))# sorted() 함수를 이용한 방법.
사라.sort()# 리스트의 sort() 메서드를 사용한 방법.
print(사라)
data=제임스파일.readline()
제임스 = data.strip().split(',') #메서드 연속 호출(method chaining) 왼쪽에서 부터 오른쪽으로 동작.
with open('julie.txt') as 줄리파일:
data=줄리파일.readline()
줄리 = data.strip().split(',')
with open('mikey.txt') as 미키파일:
data=미키파일.readline()
미키 = data.strip().split(',')
with open('sarah.txt') as 사라파일:
data=사라파일.readline()
사라 = data.strip().split(',')
print(sorted(제임스))
print(sorted(줄리))
print(sorted(미키))
print(sorted(사라))# sorted() 함수를 이용한 방법.
사라.sort()# 리스트의 sort() 메서드를 사용한 방법.
print(사라)
위에 코드를 보면 data.strip().split(',') 을 볼 수 있는데, 메서드가 연속해서 사용되었다.
이것을 메서드 연속호출이라고 하며 작동 순서는 왼쪽->오른쪽 으로 동작한다.
메서드만 연속 호출이 될까??
아니다.
함수도 연속 호출이 가능하다.
print(sorted(사라)) 처럼 함수도 연속해서 사용을 했다.
이럴 경우에는 메서드와 반대로 오른쪽->왼쪽 으로 동작한다.
실행 결과
>>>
['2-22', '2-34', '2.34', '2.45', '2:01', '2:01', '3.01', '3:10', '3:21']
['2-23', '2.11', '2.59', '2:11', '2:23', '3-10', '3-21', '3.21', '3:10']
['2.49', '2:22', '2:38', '3.01', '3.02', '3.02', '3:01', '3:02', '3:22']
['2-25', '2-55', '2.18', '2.58', '2:39', '2:54', '2:55', '2:55', '2:58']
['2-25', '2-55', '2.18', '2.58', '2:39', '2:54', '2:55', '2:55', '2:58']
['2-22', '2-34', '2.34', '2.45', '2:01', '2:01', '3.01', '3:10', '3:21']
['2-23', '2.11', '2.59', '2:11', '2:23', '3-10', '3-21', '3.21', '3:10']
['2.49', '2:22', '2:38', '3.01', '3.02', '3.02', '3:01', '3:02', '3:22']
['2-25', '2-55', '2.18', '2.58', '2:39', '2:54', '2:55', '2:55', '2:58']
['2-25', '2-55', '2.18', '2.58', '2:39', '2:54', '2:55', '2:55', '2:58']
앞자리수만 보면 정렬은 된듯하지만....
제대로 되진 않았다.
정렬을 할때 파이썬은 문자열로 정렬한다.
무슨말인가 하면, 2는 3보다 앞에 있는 문자이고 '-'는 '.'보다 앞에 있고 '.'는 ':'보다 앞에 있다는 것이다.
여기서 제대로되 정렬이 이루어지지 않은 것은 데이터가 일관성있는 형태가 아니기 때문인다.
사람이 보기에는 모두 같은 의미이지만 컴퓨터는 아스키코드값과 같은 형태로 되기에 다른 의미라고 판단 할 수 있다.
제대로 정렬을 하기 위해서는 데이터를 일관성있게 해주는 작업을 해줘야 한다.
sanitize.py
def 동일화(time_string):
if '-' in time_string:
splitter='-'
elif ':' in time_string:
splitter=':'
else:
return(time_string)
(mins,secs) = time_string.split(splitter)
return(mins+'.'+secs)
if '-' in time_string:
splitter='-'
elif ':' in time_string:
splitter=':'
else:
return(time_string)
(mins,secs) = time_string.split(splitter)
return(mins+'.'+secs)
이 함수가 바로 리스트에 있는 ':'와 '-'을 '.'로 변형시켜준다.
ex_sorting_complete.py
with open('james.txt') as 제임스파일:
data=제임스파일.readline()
제임스 = data.strip().split(',')
with open('julie.txt') as 줄리파일:
data=줄리파일.readline()
줄리 = data.strip().split(',')
with open('mikey.txt') as 미키파일:
data=미키파일.readline()
미키 = data.strip().split(',')
with open('sarah.txt') as 사라파일:
data=사라파일.readline()
사라 = data.strip().split(',')
done_제임스=[] # 데이터를 같은 형태로 변한 것을 담을 객체
done_줄리=[]
done_미키=[]
done_사라=[]
for each_t in 제임스:
done_제임스.append(동일화(each_t))#만든 함수를 이용해 리스트내의 문자열을 일정한 형태로 변경
for each_t in 줄리:
done_줄리.append(동일화(each_t))
for each_t in 미키:
done_미키.append(동일화(each_t))
for each_t in 사라:
done_사라.append(동일화(each_t))
print(sorted(done_제임스))
print(sorted(done_줄리))
print(sorted(done_미키))
print(sorted(done_사라))
data=제임스파일.readline()
제임스 = data.strip().split(',')
with open('julie.txt') as 줄리파일:
data=줄리파일.readline()
줄리 = data.strip().split(',')
with open('mikey.txt') as 미키파일:
data=미키파일.readline()
미키 = data.strip().split(',')
with open('sarah.txt') as 사라파일:
data=사라파일.readline()
사라 = data.strip().split(',')
done_제임스=[] # 데이터를 같은 형태로 변한 것을 담을 객체
done_줄리=[]
done_미키=[]
done_사라=[]
for each_t in 제임스:
done_제임스.append(동일화(each_t))#만든 함수를 이용해 리스트내의 문자열을 일정한 형태로 변경
for each_t in 줄리:
done_줄리.append(동일화(each_t))
for each_t in 미키:
done_미키.append(동일화(each_t))
for each_t in 사라:
done_사라.append(동일화(each_t))
print(sorted(done_제임스))
print(sorted(done_줄리))
print(sorted(done_미키))
print(sorted(done_사라))
실행 결과
>>>
['2.01', '2.01', '2.22', '2.34', '2.34', '2.45', '3.01', '3.10', '3.21']
['2.11', '2.11', '2.23', '2.23', '2.59', '3.10', '3.10', '3.21', '3.21']
['2.22', '2.38', '2.49', '3.01', '3.01', '3.02', '3.02', '3.02', '3.22']
['2.18', '2.25', '2.39', '2.54', '2.55', '2.55', '2.55', '2.58', '2.58']
['2.01', '2.01', '2.22', '2.34', '2.34', '2.45', '3.01', '3.10', '3.21']
['2.11', '2.11', '2.23', '2.23', '2.59', '3.10', '3.10', '3.21', '3.21']
['2.22', '2.38', '2.49', '3.01', '3.01', '3.02', '3.02', '3.02', '3.22']
['2.18', '2.25', '2.39', '2.54', '2.55', '2.55', '2.55', '2.58', '2.58']
드디어 보기 깔끔하게 정렬되어 나온다.
그럼 끝?
위에 코드가 생각보단 길다는 생각은 안드나???
중복된 것들이 많아서 복잡하진 않지만 길어져서 수정작업을 하거나 할때 귀찮거나 힘들 수 있다.
지능형 리스트
지능형 리스트는 다음과 같은 과정을 거치는 리스트를 말한다.
-
변환된 데이터를 보관할 리스트를 새로 만들고
-
원래 리스트의 모든 데이터 항목을 나열
-
나열하면서 각 데이터 항목을 변환
-
변환된 데이터를 새 리스트에 추가
위에 코드에서 보면
done_사라=[]
for each_t in 사라:
done_사라.append(동일화(each_t))
done_사라.append(동일화(each_t))
부분을 지능형 리스트로 병형해서 사용하면 편한다.
done_사라=[동일화(each_t) for each_t in 사라]
위에 코드보다 훨씬 간결해졌다.
지능형 리스트를 사용하면 이러한 점에서 분명 이득을 볼 것이다.
지능형 리스트는 리스트 안에 함수나 조건이나 반복문들을 사용하는 것으로
예를 들면
>>> 분=[1,2]
>>> 초=[m*60 for m in 분]
>>> 초
[60, 120]
>>> 초=[m*60 for m in 분]
>>> 초
[60, 120]
와 같다. 리스트 메서드도 사용이 가능하고 연속호출도 가능하다.
이것이 간단하고 좋은 것 같은데 왜 두개가 공존할까?
그것은 둘다 쓰임세가 다르기 때문이다. 좀 더 융통성있는 것은 리스트 나열(기존방법)이다.
참고 : headfirst python, 파이썬3 바이블
'프로그램 언어 > 파이썬' 카테고리의 다른 글
[파이썬3.0] 집합을 이용한 중복 제거 방법 (0) | 2014.06.24 |
---|---|
[파이썬3.0] 데이터 정렬 2 (0) | 2014.06.24 |
[파이썬3.0] 객체에 대해 (0) | 2014.06.24 |
[파이썬3.0]데이터 저장과 예외처리-finally,with절 등 (0) | 2014.06.23 |
[파이썬3.0] 피클링 (0) | 2014.06.15 |
댓글()