본문 바로가기

자료구조

[Python/파이썬] 배열 연산자 - 리스트 순서 조작 및 기타 연산자

이번 글에서는 리스트와 리스트 내의 데이터를 조작하는 방법을 배워보겠습니다! 앞의 배열 연산자와 마찬가지로 튜플 타입의 경우 수정이 불가능하기 때문에 대부분의 함수를 사용할 수 없습니다.

1. 리스트 순서 조작하기

먼저 리스트 내 데이터의 순서를 조작하는 방법들에 대해 알아보겠습니다. 데이터를 정렬 혹은 순서를 바꾸는 걸 보여드리기 위해 앞의 글과는 다른 데이터가 들어간 리스트, myList = [5, -3, 4, -1, 2]를 사용하겠습니다.

1.1. sort()와 sorted() 사용하여 리스트 정렬하기

 첫 번째로 sort()와 sorted()입니다. 두 방법 모두 리스트를 오름차순으로  정렬하고 수정하나, sort()는 리스트_이름. sort()  식으로 쓰이는 리스트형의 메서드이고, sorted(리스트명) 형식으로 쓰이는 내장 함수라는 것에서 차이가 있습니다. 그렇기 때문에 sorted()를 쓸 때에는 return을 받아줄 인자가 필요합니다. 

myList = [5,-3,4,-1,2]

# sort() 사용
a = myList.sort()
print(myList) # [-3,-1,2,4,5] <- 정렬됨
print(a) # None <- return 값이 없기 때문에 None

myList = [5,-3,4,-1,2]

# sorted()사용
b = sorted(myList)
print(myList) # [5,-3,4,-1,2] <- 정렬되지 않음
print(b) # [-3,-1,2,4,5] <- 정렬된 값을 return으로 받음

sort() 와 sorted() 모두 key와 reverse 매개변수를 가지고 있습니다. reverse는 bool 타입으로써, reverse = True를 적어줄 경우, 숫자를 내림차순으로 정렬합니다. key 같은 경우 정렬을 목적으로 하는 함수를 값으로 넣는데, 이 경우 lambda를 이용하면 편하게 함수를 추가할 수 있습니다. 

myList = [5,-3,4,-1,2]

# reverse = True 사용
myList = sorted(myList, reverse = True)
print(myList) # [5,4,2,-1,-3] <- 내림차순으로 정렬된 것을 볼 수 있음

# key = 함수 사용
myList.sort(key = lamda x:abs(x))
print(myList) # [-1,2,-3,4,5] <- 절댓값 순으로 오름차순으로 정렬된 것을 볼 수 있음

# 두개 다 사용
myList.sort(reverse = True, key = lamda x:abs(x))
print(myList) # [5,4,-3,2,-1] <- 절댓값 순으로 내림차순으로 정렬된 것을 볼 수 있음

추가로, 튜플 타입에 sort() 메서드를 사용할 경우 AttributeError을 볼 수 있으나,  sorted() 함수를 사용하면 정렬된 리스트를 return 값으로 받아볼 수 있습니다.  

myTuple = (5,-3,4,-1,2)

a = sorted(myTuple)
print(myTuple) # (5,-3,4,-1,2) 
print(a) # [-3,-1,2,4,5] <- 정렬된 리스트타입으로 반환됨

myTuple.sort() # AttributeError <- 튜플 타입에는 sort()라는 method 존재 x

1.2. reverse()와 reversed() 사용하기

sort()와 sorted()가 리스트를 정렬하는 방법이었다면, reverse()와 reversed()는 리스트의 순서를 거꾸로 바꿔줄 때 쓰입니다. 앞글과 마찬가지로 reverse()는 리스트_이름. reverse()  식으로 쓰이는 리스트형의 메서드이고, reversed(리스트명) 형식으로 쓰이는 내장 함수라는 것에서 차이가 있습니다. 

 

그렇기 때문에 reversed()를 쓸 때에는 return을 받아줄 인자가 필요하며, 추가로 반복자 타입을 반환타입(return type)으로 가지고 있기 때문에 reversed() 함수 외부에 입력받을 형식을 명시해야 합니다.  

myList = [5,-3,4,-1,2]

# reverse() 사용
a = myList.reverse()
print(myList) # [2,-1,4,-3,5] <- 리스트가 뒤집어짐
print(a) # None <- return 값이 없기 때문에 None

myList = [5,-3,4,-1,2]

# reversed()사용
b = reversed(myList) 
c = list(b) 
d = tuple(reversed(myList))

print(myList) # [5,-3,4,-1,2] <- 원본 리스트는 변함 없음
print(b) # <list_reverseiterator object at 0x0000019F84DB0FD0> <- 반환자 타입으로 변환
print(c) # [2,-1,4,-3,5] <- 반환자 타입을 리스트 타입으로 변환, 리스트가 뒤집힘
print(d) # (2,-1,4,-3,5) <- 반환자 타입을 튜플 타입으로 변환, 리스트가 뒤집혀서 튜플로 변환됨

reversed() 함수 경우에는 튜플 타입의 데이터를 집어넣어 데이터의 순서를 뒤바꿀 수 있습니다. 다만, 위의 예와 마찬가지로 return 값의 타입을 지정해 주어야 반환자 타입이 아닌 원하는 타입으로 받을 수 있습니다.

myTuple = (5,-3,4,-1,2)

# reversed()사용
a = list(reversed(myTuple)) 
b = tuple(reversed(myList))

print(myList) # (5,-3,4,-1,2) <- 원본 튜플에는 변함 없음
print(a) # [2,-1,4,-3,5] <- 데이터가 뒤집힘 -> 반환자 타입 -> 리스트 타입으로 변환됨
print(b) # (2,-1,4,-3,5) <- 데이터가 뒤집힘 -> 반환자 타입 -> 튜플 타입으로 변환됨

reverse()나 reversed()의 경우 괄호 안에 값을 받지 않습니다. 그렇기 때문에 , 만약 값을 넣는다면 TypeError를 볼 수 있습니다.

myList = [5,-3,4,-1,2]
myTuple = (5,-3,4,-1,2)

# 발생될 수 있는 Error
a = reversed(myList, key= lambda x : abs(x)) # TypeError <- reversed 괄호 안에는 데이터만!
myTuple.reverse() # AttributeError <- 튜플에는 reverse()가 없어요!!

2. 리스트 내의 데이터 조작하기

두 번째로 리스트 내의 데이터와 관련된 함수 및 키워드 사용 방법에 대해 알아보겠습니다. 함수와 키워드가 많이 있기 때문에 몇몇 함수와 키워드는 그림과 코드로 설명을 대체하겠습니다.

2.1. index() 사용하기

index() 함수의 경우 괄호 안에 리스트에 존재하는 데이터 값을 넣으면 그 데이터가 존재하는 위치 값을 반환합니다. index(찾으려는 데이터 값, 시작범위, 종료범위) 방식으로 사용해서, 데이터를 찾으려는 구간을 설정해 줄 수 있습니다. 다만 주의해야 할 점은, 리스트 안에 같은 데이터 값이 여러 개 존재하는 경우, 가장 앞에 있는 데이터의 위치만 return 합니다.

myList = [1,2,3,4,3,5]
myTuple = (1,2,3,4,3,5)

a = myList.index(3)
print(a) # 2 <- 가장 앞에 있는 데이터의 인덱스
b = myList.index(3,3,5)
print(b) # 4 <- 인덱스 범위 내에서 가장 앞에 있는 데이터의 인덱스
c = myTuple.index(3)
print(c) # 2 <- 튜플에서도 사용 가능!!

또한, 만약 범위 내에 찾으려는 데이터 값이 없다면,ValueError를 볼 수 있습니다. 튜플에서도 사용 가능합니다!

myList = [1,2,3,4,3,5]

a = myList.index(6)
print(a) # ValueError <- 6이라는 데이터가 없음
b = myList.index(3,0,2)
print(b) # ValueError <- 3이라는 데이터가 0과 2 전에 없음

 

2.2. count() 사용하기

count() 함수는 괄호 안에 리스트에 존재하는 데이터 값을 넣으면 그 데이터가 리스트 내에 몇 개 존재하는지를 반환합니다. count(데이터 값) 방식으로 사용해서, 리스트 내 데이터의 수를 찾을 수 있습니다. 만약 데이터 값이 리스트 내에 존재하지 않는다면 0을 반환합니다.

myList = [3,'3',[3],3,(3,),33]
myTuple = (5,-3,4,-1,2)

a = myList.count(3) 
b = myTuple.count(5) 
c = myList.count(2) 

print(a) # 2 <- 3이라는 데이터가 2개 있음
print(b) # 1 <- 5라는 데이터가 튜플에 1개 있음
print(c) # 0 <- 2라는 데이터는 없기때문에 0을 반환

2.3. len() 사용하기

len() 함수는 괄호 안에 리스트나 튜플을 넣으면 그 배열의 크기를 반환합니다.  len(리스트명) 방식으로 사용하며, 반환되는 값으로 리스트의 크기를 찾을 수 있습니다. 만약 리스트가 비어있다면 0을 반환합니다.

myList = [3,'3',[3],3,(3,),33]
myTuple = (5,-3,4,-1,2)
tmpList = [ ]

a = len(myList)
b = len(myTuple)
c = len(tmpList)

print(a) # 6 <-리스트에 원소가 6개 있음
print(b) # 5 <-튜플에 원소가 5개 있음
print(c) # 0 <-리스트가 비어있기에 0

2.4. in과 not in 사용하기

in 과 not in 같은 경우 데이터가 리스트에 포함되어 있는지를 확인할 때 쓰는 방법입니다. 주로 "데이터 in 리스트명" 방법으로 쓰이며, 만약 데이터가 리스트에 포함되어 있을 경우 True를, 포함되어 있지 않을 경우 False를 반환받습니다. 

myList = [3,'3',[3],3,(3,),33]
myTuple = (5,-3,4,-1,2)

print(3 in myList) # True
print(6 in myTuple) # False

print(4 not in myList) # True
print(-1 not in myTuple) # False

2.5. max()와 min() 사용하기

max()와 min()은 배열 내의 최댓값과 최솟값을 찾을 때 쓰입니다. 다만 주의할 점은 리스트가 비교가 가능한 같은 형태(int 혹은 str)로 되어있어야  한다는 점입니다. 만약 리스트 안에 str타입과 int타입 모두 들어있고, 위의 두 함수를 사용한다면 TypeError를 볼 수 있습니다. 2차원의 배열에서도 사용 가능합니다.

myList = [1,2,3,4,5]
tmpList = ['1','2','3','4','5']
errorList = [1,2,'3',4,'5']
tList = [[1],[2],[3],[4],[5]]

a = min(myList)
b = max(tmpList)
c = max(errorList) # TypeError -> int타입과 str타입 모두 리스트 안에 있음
d = max(tList)

print(a) # 1
print(b) # '5'
print(d) # [5]

2.6. all()과 any() 사용하기

all()은 모든 원소가 True라면 True를 리턴합니다. 즉, 리스트 안에 0, False, 빈 배열이나 빈 문자열이 없다면  True를 리턴합니다. 만약 False 값이 하나라도 존재한다면 False를 리턴합니다.

myList = [3,'3',[3],(3,),33] # 데이터가 모두 True인 리스트
myList2 = [3,'3',[ ],(3,),33] # 데이터 한개만 False인 리스트

tmpList = ['',[ ],(), False, 0] # 데이터가 모두 False인 리스트
tmpList2 = ['',[ ],(), False, 1] # 데이터 한개만 True인 리스트

print(all(myList)) #True <- all() 사용시 모두 True일때만 True
print(all(myList2)) #False
print(all(tmpList)) #False
print(all(tmpList2)) #False

any()의 경우 빈 배열이 아니라면 True를 반환합니다. 즉, 모든 리스트 데이터가 False값이 아니라면 True를 리턴합니다. 만약, 모든 데이터가 False값이라면 False를 리턴합니다.  

myList = [3,'3',[3],(3,),33] # 데이터가 모두 True인 리스트
myList2 = [3,'3',[ ],(3,),33] # 데이터 한개만 False인 리스트

tmpList = ['',[ ],(), False, 0] # 데이터가 모두 False인 리스트
tmpList2 = ['',[ ],(), False, 1] # 데이터 한개만 True인 리스트

print(any(myList)) # True
print(any(myList2)) # True
print(any(tmpList)) # False <- any()사용 시 모두 False일때만 False
print(any(tmpList2)) # True

2.7. zip() 사용하기

zip()함수의 경우 인수로 지정된 배열 또는 문자열의 각 원소들을 원소 개수가 가장 작은 것을 기준으로 동일한 인덱스로 묶어서 zip타입으로 반환시켜줍니다. zip()타입의 반환자를 return하기 때문에 앞의 reversed와 마찬가지로 zip()함수 앞에 list()나 tuple()을 사용하여 원하는 배열 타입을 적어서 사용해야합니다. 

newList = list(zip([1,2,3,4,5],('1','2','3','4'), ['one','two','three'], 'abcdefg'))
print(newList) #[(1, '1', 'one', 'a'), (2, '2', 'two', 'b'), (3, '3', 'three', 'c')]