파이썬 자료구조 :: 리스트 list (*)




프로그래머스 기초 단계를 풀다보니 자료구조가 많이 부족해서 정리를 해볼려고 한다. 

[ 리스트 list 정리편]





참고 사이트 : 제대로 파이썬 (위키독스) 



list 특징 

Sequence (순서)가 있어서, 인덱스로 값을 찾을 수 있다. 

    (Sequence : list, tuple / Non-Sequence : set, dict) 

변경 가능한 객체(mutable)라서 생성한 후에도 수정하거나 제거, 추가가 가능  

    (mutable : list, dict, set / immutable : tuple, str ) 


-----------------------------------


list 선언 

a = []

b = list()

c = [1, 2, 'Life', 'is']

d = [1, 2, ['Life', 'is']]


[프로그래머스 Day 7 - 카운트 업] 문제 

리스트를 선언하고, 값을 넣는 문제를 푸는 방법이 3가지가 있어서 정리해봄 

① 정석 : 빈 리스트 선언하고, for문 돌리면서 하나씩 append해서 값 추가 

def solution(start_num, end_num):
    answer = []
    for i in range(start_num, end_num+1):
        answer.append(i)
    return answer 


list [  ] 괄호 안에서 리스트 컴프리헨션

def solution(start_num, end_num):
    return [i for i in range(start_num, end_num+1)]

list ( ) 클래스 안에서, range 함수 활용 
def solution(start_num, end_num):
    return list(range(start_num, end_num+1))



-----------------------------------


list 인덱싱, 슬라이싱 

a[0], a[3] 

a[0] + a[3] 

a[ : 3], a[2 : 5], a[2 : ], a[ : ], a[-3 : ] ~부터 ~까지

a[-1], a[-3] 뒤에서 -n번째 출력

a[ : : 2 ] 2칸씩 스텝(간격) 

a[ : : -1] 역순출력 


이중 리스트 인덱싱 

>>> a = [1, 2, 3, ['a', 'b', 'c']]
>>> a[0]
1
>>> a[-1]
['a', 'b', 'c']
>>> a[3]
['a', 'b', 'c']
>>> a[-1][0]
'a'

삼중 리스트 인덱싱 
>>> a = [1, 2, ['a', 'b', ['Life', 'is']]]
>>> a[2][2][0]
'Life'
중첩 리스트 슬라이싱
>>> a = [1, 2, 3, ['a', 'b', 'c'], 4, 5]
>>> a[2:5]
[3, ['a', 'b', 'c'], 4]
>>> a[3][:2]
['a', 'b']



-----------------------------------



list 연산하기

+ 더하기

리스트 더하기, 인덱스 요소 값 더하기 둘다 가능 

a[3] + a[5]

[1, 2, 3] + [3, 4, 5] 

a + b #각각 리스트 


list + str는 오류가 나기때문에 주의 

>>> a = [1, 2, 3]
>>> a[2] + "hi"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'


list를 str로 형변환하거나, str를 list로 형변환해서 타입을 통일해야함  

>>> str(a[2]) + "hi"
3hi 


for 문으로 리스트를 돌릴때, 자주하는 실수이다.  

### 오류남. 틀린 문법 
arr = []
for i in range(5) :
  if i % 2 == 0 :
    arr += i
arr

arr += i 이 부분에서 i 는 int형인데, arr는 타입이 list라서 충돌이 생긴다. 

list + int는 합쳐질 수 없기때문이다. 


그래서 아래처럼 arr += [i] 로 합쳐야함 .  

# 이렇게 해야함 
arr = []
for i in range(5) :
  if i % 2 == 0 :
    arr += [i]
arr




* 반복하기 

>>> a = [1, 2, 3]
>>> a * 3
[1, 2, 3, 1, 2, 3, 1, 2, 3]



-----------------------------------




list 수정 

해당 인덱스에 값을 그냥 넣으면됨. 덮어쓰기됨
>>> a = [1, 2, 3]
>>> a[2] = 4
>>> a
[1, 2, 4]


-----------------------------------



list 추가

추가하는 방법에는 2가지 방법이 있다. 

① append  ② insert  

① list.append(value)

리스트의 가장 마지막 자리에 새로운 값을 추가한다. 

>>> a = [1, 2, 3]
>>> a.append(4)
>>> a
[1, 2, 3, 4]


append 메서드 안에 리스트를 추가하면, 중첩된 리스트를 만들 수 있음 

>>> a.append([5, 6])
>>> a
[1, 2, 3, 4, [5, 6]]


② list.insert(idx, value)

인덱스 위치를 지정해서 새로운 값을 추가한다. 
>>> a = [1, 2, 3]
>>> a.insert(0, 4)
>>> a
[4, 1, 2, 3]



-----------------------------------



list 삭제

삭제하는 방법에는 3가지 방법이 있다. 

① del  ② remove   ③ pop 


① del a[idx]  

>>> a = [1, 2, 3]
>>> del a[1]
>>> a
[1, 3]

여러 요소를 삭제하고 싶으면, 

del a[1]

del a[4] 

이렇게 하나씩 하나씩 del 함수를 써서 삭제해야함 


연달아 있는 요소라면, 리스트 슬라이싱 활용 가능 

>>> a = [1, 2, 3]
>>> a[2] = 4
>>> a
[1, 2, 4]



② list.remove(value)

리스트에서 첫번째로 나오는 value 값을 삭제하는 함수. 하나만 삭제가 된다. 

value값이 리스트에 여러개 있어도, 가장 처음에 나오는 값 하나만 삭제가 됨 

>>> a = [1, 2, 3, 1, 2, 3]
>>> a.remove(3)
>>> a
[1, 2, 1, 2, 3]


③ list.pop(idx)

리스트의 idx 자리에 맞는 요소를 리턴하고, 삭제함 

idx의 기본값은 공백 = 가장 마지막 자리 = list.pop() = 가장 마지막 요소 삭제 

>>> a = [1, 2, 3]
>>> a.pop()
3
>>> a
[1, 2]

 

idx를 1로하면,  list.pop(1) = list[1] 요소 삭제 

>>> a = [1, 2, 3]
>>> a.pop(1)
2
>>> a
[1, 3]


-----------------------------------



list 정렬

역방향으로 정렬하는 방법에는 4가지 방법이 있다. 

① sort  ② sorted   ③ reverse  ④ 리스트 슬라이싱


① sort 메서드 

list.sort(key=None, reverse=False)

    ① key (선택): 정렬의 기준을 제공하는 함수

    ② reverse (선택): boolen 타입, 기본값은 False로 오름차순, True는 내림차순

sort 메서드는 원본 리스트를 자체를 정렬해서, 원본 자체가 변경되는게 특징이다. 

numbers = [5, 2, 8, 1, 6]

# 오름차순으로 정렬
numbers.sort()
print(numbers)  # 출력: [1, 2, 5, 6, 8]

# 내림차순으로 정렬
numbers.sort(reverse=True)
print(numbers)  # 출력: [8, 6, 5, 2, 1]

# 절댓값을 기준으로 정렬
numbers.sort(key=abs)
print(numbers)  # 출력: [1, 2, 5, 6, 8]

원본은 유지하고 정렬한 리스트는 다른 곳에 저장하고 싶다면 sorted 함수를 사용해야 한다. 



② sorted 함수 

변수 = sorted(iterable, key=None, reverse=False)

    ② key (선택): 정렬의 기준을 제공하는 함수

    ③ reverse (선택): boolen 타입, 기본값은 False로 오름차순, True는 내림차순

numbers = [5, 2, 8, 1, 6]

# 오름차순으로 정렬된 새로운 리스트 생성
sorted_numbers = sorted(numbers)
print(sorted_numbers)  # 출력: [1, 2, 5, 6, 8]

# 내림차순으로 정렬된 새로운 리스트 생성
reverse_sorted_numbers = sorted(numbers, reverse=True)
print(reverse_sorted_numbers)  # 출력: [8, 6, 5, 2, 1]

# 절댓값을 기준으로 정렬된 새로운 리스트 생성
abs_sorted_numbers = sorted(numbers, key=abs)
print(abs_sorted_numbers)  # 출력: [1, 2, 5, 6, 8]


sorted() 함수는 원본 리스트를 변경하지 않고 새로운 정렬된 리스트를 반환하기 때문에 

기존의 데이터를 유지하면서 정렬된 데이터를 얻고 싶을 때 유용


프로그래머스 Day 9 - 접미사 배열 

특정 인덱스부터 시작하는 문자열을 모두 저장하고, 정렬한 리스트를 출력하는 문제이다. 


이 문제를 풀때, sorted 함수를 이용한다. 
def solution(my_string):
    answer = []
    for i in range(len(my_string)):
        answer.append("".join(c for c in my_string[i:]))
    return sorted(answer)


위 문제를 간결하게 작성하면 아래와 같다. 

def solution(my_string):
    answer = sorted(["".join(c for c in my_string[i:]) for i in range(len(my_string))])
    return answer




③ reverse 메서드 

list.reverse()

reverse 메서드는 sort 메서드처럼 원본 리스트 자체를 정렬(변경)시킨다. 

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

# 리스트를 역순으로 뒤집기
my_list.reverse()
print(my_list)  # 출력: [5, 4, 3, 2, 1]


reverse 메서드랑 sort(reverse=True / False) 둘 다 똑같아 보이지만 리스트 내용이 무엇이냐에 따라 달라진다. 

list.reverse() 는 리스트에 들어있는게, 숫자든 문자열이든 뭐든 리스트를 뒤집는거에 중점을 두기때문에 정렬은 되지 않는다. 

list.sort(reverse=True)는 리스트의 숫자를 내림차순 정렬하는 것이다. 




④ 리스트 슬라이싱

변수 = list[ : : -1 ]

슬라이싱은 [ start : stop : step ]으로 마지막 step이 -1이면, 뒤에서 앞으로 출력을 하는 것

my_string = "Hello, World!"
reversed_string = my_string[::-1]
print(reversed_string)  # 출력: "!dlroW ,olleH"


reverse() 메서드는 원본 리스트 자체를 뒤집는거지만, 

list[ : : -1 ]는 원본 리스트는 그대로 두고, 뒤집은 리스트를 다른 곳에 저장하는 차이가 있음



전체 리스트를 뒤집어서 출력할려는게 아닌, 일부 인덱스에 해당하는 부분만 뒤집기를 원한다. 

list.reverse(), list.sort(reverse=True), sorted(list, reverse=True) 이 세가지는 모두 전체 리스트를 뒤집는거라서 활용할 수 없다. 

인덱스 슬라이싱을 활용해야하는데, 주의할 점이 있어서 추가한다. 

list[ s : e+1 ] 만큼만 뒤집고 싶은 경우에 list[ s : e+1 : -1 ] 이렇게 쓰면 안된다. 

왜냐하면, step -1이 되면서 s에서 e+1까지의 범위에 대해 역순으로 슬라이싱하려고 하기 때문에, se+1보다 더 뒤에 위치한 것으로 간주된다. 하지만, 이 문제에서 s는 e 보다 앞에 있기때문에 원하는 결과값이랑 다르게 출력이된다.


def solution(my_string, queries):
    l = list(my_string)
    for s, e in queries : 
        l = l[:s] + l[s:e+1][::-1] + l[e+1:]  #l[e:s-1:-1] or l[s:e+1][::-1]
    return ''.join(l) 

그래서, 이 문제 코드처럼 list[ s : e+1 ][ : : -1 ] 또는 list [e : s-1 : -1] 로 인덱스 슬라이싱을 조정해야한다. 




-----------------------------------


list 메서드

① count 

list.count(value) 

리스트에 해당 value값의 요소가 몇개인지 갯수 조사 

>>> a = [1, 2, 3, 1]
>>> a.count(1)
2


② extend 

list.extend(iterable) 
리스트와 리스트를 합칠때, 사용한다.

append(value)는 요소 하나의 값을 추가하는 것이지만,

extend(iterable)은 리스트를 넣을 수 있음 

>>> a = [1, 2, 3]
>>> a.extend([4, 5])
>>> a
[1, 2, 3, 4, 5]
>>> b = [6, 7]
>>> a.extend(b)
>>> a
[1, 2, 3, 4, 5, 6, 7]
a 리스트에 b 리스트를 추가한 경우이다. 

a += [4, 5]

리스트에 + 연산해서 다른 리스트 합친거랑 같은 역할을 한다. 

리스트 컴프리헨션을 활용해도 같은 기능 




③ index 

list.index(x[, start[, end]])

    ① x: 찾을 값.

    ② start (선택): 검색을 시작할 인덱스. 기본값은 0

    ③ end (선택): 검색을 종료할 인덱스. 기본값은 리스트의 마지막 인덱스

fruits = ["apple", "banana", "orange", "apple", "grape"]

# "apple"의 첫 번째 등장하는 인덱스를 찾기
index1 = fruits.index("apple")
print(index1)  # 출력: 0

# 두 번째 "apple"의 인덱스를 찾기 (시작 인덱스를 지정)
index2 = fruits.index("apple", 1)
print(index2)  # 출력: 3

# "orange"의 인덱스를 찾기 (시작과 종료 인덱스를 지정)
index3 = fruits.index("orange", 1, 3)
# ValueError: 'orange' is not in list within the specified indices
찾을려는 해당 값이 리스트에 없으면 ValueError 예외가 발생한다. 마치 위 코드의 index3 처럼, 찾을려는 "orange"가 없을때


④ join 

seperator.join(iterable)

    ① seperator : 각 요소 사이에 삽입될 문자열 

my_list = ["apple", "banana", "orange"]

result = " ".join(my_list)
print(result)  # 출력: "apple, banana, orange"
리스트에 들어있는 문자열 값을 합쳐서 출력하는 역할을 한다 .
-----------------------------------





list 함수

① len 

len(list)


② max / min 

new = max(iterable)
new = min(iterable) 

③ sum

new = sum(iterable, start = 0) 
numbers = [1, 2, 3, 4, 5]

total = sum(numbers)
print(total)  # 출력: 15

total_with_start = sum(numbers, start=10)
print(total_with_start)  # 출력: 25
※ sum() 함수는 숫자가 아닌 요소가 있는 경우 TypeError를 일으킬 수 있으므로 주의

댓글

이 블로그의 인기 게시물

KT 에이블스쿨 : 대구광역시 공공데이터 활용 창업경진대회 준비

[KT 에이블스쿨 - IT 트랜드] 국내외 AI 관련 규제

KT 에이블스쿨 : 핀테크 아이디어 공모전