#!/usr/bin/env python # coding: utf-8 # *** # *** # # 10. 리스트의 활용 # *** # *** # *** # ## 1 리스트 정렬하기 # *** # ### 1-1 리스트의 sort 메소드 # - L.sort() 함수는 리스트 L 자체를 변경하며 리턴값을 반환하지 않는다. # In[1]: L = [1, 5, 3, 9, 8, 4, 2] print(L.sort()) print(L) # - 파이썬2에서는 cmp(a,b) 내장 함수가 지원되었으나, # - 파이썬3부터는 cmp(a,b) 내장 함수가 지원되지 않는다. # In[1]: print(cmp(1,2)) print(cmp(5,2)) print(cmp('abc', 'abc')) # -1 # 1 # 0 # In[3]: # cmp(a, b) # if a < b: return -1 # if a > b: return 1 # if a == b: return 0 def cmp(a, b): return (a > b) - (a < b) print(cmp(1, 2)) print(cmp(5, 2)) print(cmp('abc', 'abc')) # - Python2: 기본 정렬 방식을 변경하려면 cmp(a, b)와 같은 비교 함수를 직접 만들어서 sort() 함수의 인자로 넣는다. # - Python3: 기본 정렬 방식을 변경할 수 없다. # In[4]: def mycmp(a, b): # 대소관계에 따른 순서를 반대로 바꾸었음 return cmp(b, a) L = [1, 5, 3, 2, 4, 6] print(L) L.sort(cmp=mycmp) # 역순으로 정렬 # - 여러 튜플을 요소로 지닌 리스트인 경우, 튜플의 첫번째 값이 아닌 다른 위치에 있는 값을 기준으로 정렬 # In[5]: #Python2 기준 예제 def cmp_1(a1, a2): return cmp(a1[1], a2[1]) def cmp_2(a1, a2): return cmp(a1[2], a2[2]) L = [('lee', 5, 38), ('kim', 3, 28), ('jung', 10, 36)] L.sort() print('sorted by name:', L) L.sort(cmp=cmp_1) print('sorted by experience:', L) L.sort(cmp=cmp_2) print('sorted by age:', L) # - [중요] **Python3: sort의 인자인 key에 객체가 지닌 원소들 내에 키값을 지정하는 함수 지정가능** # - key 인자에 함수가 할당되어 있으면 각 리스트 원소에 대해 기본 비교함수 호출 직전에 key 함수를 먼저 호출한다. # In[1]: #Python3 기준 예제 L = [('lee', 5, 38), ('kim', 3, 28), ('jung', 10, 36)] def get_key_value(a): return a[1] L.sort() print('sorted by name:', L) L.sort(key=get_key_value) print('sorted by experience:', L) # In[2]: #Python3 기준 예제 S = ['loh', 'kim', 'jung'] def get_key_value(a): return a[1] S.sort() print('sorted by the first character:', S) S.sort(key=get_key_value) print('sorted by the second character:', S) # In[3]: L = ['123', '34', '56', '2345'] L.sort() print(L) L.sort(key=int) print(L) # - sort() 함수 인자로 reverse 값을 받을 수 있다. # - 디폴트 reverse 인자값은 False # - reverse 인자값을 True로 주면 역순으로 정렬됨 # In[12]: L = [1, 6, 3, 8, 6, 2, 9] L.sort(reverse=True) # L.sort(reverse = 1) print(L) L.sort(reverse=False) # L.sort(reverse = 1) print(L) # ### 1-2 sorted 내장 함수 # - sorted() 내장함수는 L 자체에는 내용 변경 없이 정렬이 되어진 새로운 리스트를 반환한다. # In[13]: L = [1, 6, 3, 8, 6, 2, 9] newList = sorted(L) print(newList) print(L) # In[14]: for ele in sorted(L): print(ele, end=" ") # - Python2: sorted() 함수의 두번째 인자로 cmp를 지정하는 함수 할당 가능 # - 지정된 cmp 함수는 1, 0, -1만 Return # # - Python3: sorted() 함수의 두번째 인자로 key를 지정하는 함수 할당 가능 # - 지정된 key 함수가 할당되어 있으면 각 리스트 원소에 대해 기본 비교함수 호출 직전에 key 함수를 먼저 호출한다. # In[15]: def mycmp(a1, a2): # 대소관계에 따른 순서를 반대로 바꾸었음 return cmp(a2, a1) L = [1, 5, 3, 2, 4, 6] print(sorted(L, key=mycmp)) # 역순으로 정렬 print(L) # ['123', '2345', '34', '56'] # ['34', '56', '123', '2345'] # In[4]: #Python3 기준 예제 L = [ ('lee', 5, 38), ('kim', 3, 28), ('jung', 10, 36)] def get_key_value(a): return a[1] print(sorted(L)) print(L) print() print(sorted(L, key=get_key_value)) print(L) # In[5]: #Python3 기준 예제 S = ['loh', 'kim', 'jung'] def get_key_value(a): return a[1] print(sorted(S)) print(S) print() print(sorted(S, key=get_key_value)) print(S) # - 인자로 reverse와 key 지정 가능 # In[15]: L = [1, 6, 3, 8, 6, 2, 9] print(sorted(L, reverse=True)) # In[16]: L = ['123', '34', '56', '2345'] print(sorted(L)) print(sorted(L, key=int)) print(sorted(L, key=int, reverse=True)) # ### 1-3 L.reverse() 와 reversed() 내장 함수 # - L.reverse()도 반환값이 없다. # - 즉, L 자체를 역순으로 뒤집는다. # - [주의] 역순 정렬이 아니다. # In[17]: L = [1, 6, 3, 8, 6, 2, 9] print(L.reverse()) print(L) # In[18]: L = [1, 6, 3, 8, 6, 2, 9] L.reverse() # 역순으로 뒤집는다. for ele in L: print(ele + 2, end=" ") print() L.reverse() # 다시 원상태로 복귀시킨다. print(L) # - reversed() 내장함수는 sorted() 처럼 내용이 뒤집힌 리스트를 반환한다. # - sorted() 처럼 원래 리스트 내용에는 변함없다. # In[19]: L = [1, 6, 3, 8, 6, 2, 9] print(L) for ele in reversed(L): print(ele + 2, end=" ") print() print(L) # *** # ## 2 리스트 내포(List Comprehension) # *** # - 다음은 고등학교 수학에서 배운 집합의 표기 방법이다. # - A = {x^2 | x in {0, ..., 9}} # - B = {1, 2, 4, 8, 16, ..., 2^16} # - C = {x | x in S and x is odd} # # - 파이썬의 리스트 내포(list comprehension)는 바로 위 집합 표기법과 유사한 방식의 리터럴이다. # - 위 집합들을 리스트 내포 방식으로 표현하면 다음과 같다. # - A = [x**2 for x in range(10)] # - B = [2**i for i in range(17)] # - C = [x for x in S if x % 2 == 1] # - 일반적인 리스트 생성법 # In[20]: L = [] for k in range(10): L.append(k*k) print(L) # - 위 코딩은 리스트 내포 리터럴 방식을 활용해서 아래와 같이 변경할 수 있다. # In[21]: L = [k * k for k in range(10)] print(L) # - 리스트 내포 리터럴 #
# [expression for expr1 in sequence1
#               for expr2 in sequence2 
#               ...
#               for exprN in sequenceN
#               if condition]
# 
# # - 위 리터럴은 다음의 일반적인 for 문의 리털러과 동일 #
# l = []
# for expr1 in sequence1:
#   for expr2 in sequence2:
#       ...
#          for exprtN in sequenceN:
#             if condition:
#                l.append(expression)
# 
# # # - expression의 평가 결과 반드시 한 개의 원소가 나와야 한다. # - 틀린 예: [ x, y for x in seq1 for y in seq2 ] # # - 만약 두 개의 이상의 평가 결과가 나오면 튜플 등으로 감싸 주어야 한다. # - 올바른 예: [ (x, y) for x in seq1 for y in seq2 ] # # # In[22]: L = [k * k for k in range(10) if k % 2] # 홀수의 제곱만 리스트로 형성 print(L) # - 위의 리스트 내포 코드는 아래와 동일 # In[23]: L = [] for k in range(10): if k % 2: L.append(k*k) print(L) # - 두 개의 시퀀스 자료형에 대해 각각의 원소에 대한 쌍을 튜플 형태로 만들면서 리스트에 저장하는 코드 # In[24]: seq1 = 'abc' seq2 = (1, 2, 3) print([(x, y) for x in seq1 for y in seq2]) # In[25]: seq1 = 'abc' seq2 = (1, 2, 3) l = [] for x in seq1: for y in seq2: l.append((x, y)) print(l) # - 20보다 작은 2의 배수와 3의 배수에 대해 그 두 수의 합이 7의 배수인 것들에 대해 그 두 수의 곱을 출력하는 코드 # In[26]: L = [(i, j, i*j) for i in range(2, 20, 2) for j in range(3, 20, 3) if (i + j) % 7 == 0] print(L) # - 문장 내 단어의 길이 출력 # In[27]: words = 'The quick brown fox jumps over the lazy dog'.split() stuff = [[w.upper(), w.lower(), len(w)] for w in words] for i in stuff: print(i) # - 피타고라스 삼각형의 각 3변의 길이 리스트 (조건: 각 변 x, y, z의 길이는 30 보다 작아야 하며, x <= y <= z 이어야 함) # In[17]: k = [(x,y,z) for x in range(1,30) for y in range(x,30) for z in range(y,30) if x**2 + y**2 == z**2] print(k) #

참고 문헌: 파이썬(열혈강의)(개정판 VER.2), 이강성, FreeLec, 2005년 8월 29일