코딩도장_Unit 22. 리스트와 튜플 응용하기

김민주·2021년 12월 30일
0

AIFFEL_풀잎스쿨

목록 보기
11/23
post-thumbnail

22.1 리스트 조작하기

22.1.1 리스트에 요소 추가하기

리스트에 요소를 추가하는 메서드는 3가지가 있다.
append, extend, insert

1. append

  • append(요소) : 리스트 끝에 요소 하나 추가, 빈 리스트에 값 추가도 가능
  • append(리스트) : 리스트 안에 리스트 생성 (중첩 리스트)
  • append는 항상 리스트의 길이가 1씩 증가
# 리스트 끝에 요소 추가
>>> a = [10, 20, 30]
>>> a.append(500)
>>> a  # 메서드를 호출한 리스트가 변경되며 새 리스트는 생성되지 않음 
[10, 20, 30, 500]  
>>> len(a)
4

# 빈 리스트에 값 추가
>>> a = []
>>> a.append(10)
>>> a
[10]

# 리스트 안에 리스트(중첩리스트)
>>> a = [10, 20, 30]
>>> a.append([500, 600])
>>> a
[10, 20, 30, [500, 600]]
>>> len(a)
4  # 리스트 a의 길이는 5가 아닌 4

2. extend

  • extend(리스트) : 리스트끝에 다른 리스트를 연결하여 확장
  • extend는 리스트의 길이가 전달된 리스트의 길이만큼 증가
  • extend에 전달된 리스트의 요소를 전달하고자 하는 다른 리스트에 추가 → 결과적으로 리스트와 리스트를 연결한 모양
>>> a = [10, 20, 30]
>>> a.extend([500, 600])
>>> a
[10, 20, 30, 500, 600]  # 전달된 리스트의 요소를 a에 추가
>>> len(a)
5  # 길이가 전달된 리스트 길이만큼 증가  

3. insert

  • insert(인덱스, 요소) : 리스트의 특정 인덱스에 요소 하나 추가
    [자주 사용하는 insert패턴]
  • insert(0, 요소) : 리스트의 맨 처음에 요소 추가
  • insert(*len(리스트), 요소) : 리스트의 끝에 요소 추가
    *len(리스트)는 마지막 인덱스보다 1 더 크기 때문에 리스트 끝에 값 추가할 때 자주 사용
  • insert에 리스트를 넣으면 append처럼 리스트 안에 리스트가 들어간다. (중첩 리스트)
  • 리스트 중간에 요소 여러 개 추가 → 슬라이스에 요소 할당하기 활용
# insert(인덱스, 요소)
>>> a = [10, 20, 30]
>>> a.insert(2, 500)  # 인덱스 2에 500 추가
>>> a
[10, 20, 500, 30]
>>> len(a)
4

# insert(0, 요소)
>>> a = [10, 20, 30]
>>> a.insert(0, 500)
>>> a
[500, 10, 20, 30]  # 맨 처음에 500 추가

# insert(len(리스트), 요소)
>>> a = [10, 20, 30]
>>> a.insert(len(a), 500)
>>> a
[10, 20, 30, 500]  # 끝에 500 추가

# 리스트 안에 리스트 (중첩 리스트)
>>> a = [10, 20, 30]
>>> a.insert(1, [500, 600])
>>> a
[10, [500, 600], 20, 30]

# 리스트 중간에 요소 여러 개 추가
>>> a = [10, 20, 30]
>>> a[1:1] = [500, 600]  
# 시작 인덱스와 끝 인덱스를 같게 지정하면 
해당 인덱스 요소를 덮어쓰지 않으면서 요소 여러 개를 중간에 추가
>>> a
[10, 500, 600, 20, 30]

22.1.2 리스트에 요소 삭제하기

리스트에서 요소를 삭제하는 메서드는 2가지가 있다.
pop, remove

1. pop

  • pop() : 리스트의 마지막 요소를 삭제한 뒤 삭제한 요소 반환
  • pop(인덱스) : 해당 인덱스의 요소를 삭제한 뒤 삭제한 요소 반환
  • pop대신 del을 사용해도 무방
# 마지막 요소 삭제&반환
>>> a = [10, 20, 30]
>>> a.pop()
30
>>> a
[10, 20]

# 특정 인덱스 요소 삭제&반환
>>> a = [10, 20, 30]
>>> a.pop(1)  # 인덱스 1의 요소 삭제
20            # 반환
>>> a
[10, 30]

# pop대신 del
>>> a = [10, 20, 30]
>>> del a[1]  # 삭제된 요소를 반환하진 않음
>>> a
[10, 30]

2. remove

  • remove(값) : 리스트에서 특정 값을 찾아서 삭제
  • 같은 값이 여러 개 있을 경우 처음 찾은 값 삭제
>>> a = [10, 20, 30]
>>> a.remove(20)
>>> a
[10, 30]

# 같은 값이 여러 개 있을 경우
>>> a = [10, 20, 30, 20]
>>> a.remove(20)
>>> a
[10, 30, 20]  # 처음 찾은 값 삭제

📎 참고) 리스트로 스택과 큐 만들기
리스트 메서드로 스택(stack)과 큐(queue)를 만들 수 있다. 🔎

22.1.3 리스트에서 특정 값의 인덱스 구하기

  • index(값) : 리스트에서 특정 값의 인덱스를 구한다.
  • 같은 값이 여러 개일 경우 처음 찾은 인덱스(가장 작은 인덱스)를 구한다.
>>> a = [10, 20, 30, 15, 20, 40]
>>> a.index(20)
1  # 처음 찾은 인덱스 출력

22.1.4 특정 값의 개수 구하기

  • count(값) : 리스트에서 특정 값의 개수를 구한다.
>>> a = [10, 20, 30, 15, 20, 40]
>>> a.count(20)
2

22.1.5 리스트의 순서 뒤집기

  • reverse() : 리스트에서 요소의 순서를 반대로 뒤집는다.
>>> a = [10, 20, 30, 15, 20, 40]
>>> a.reverse()
>>> a
[40, 20, 15, 30, 20, 10]

22.1.6 리스트의 요소 정렬하기

  • sort() 또는 sort(reverse=False) : 리스트의 요소를 작은 순서대로 정렬(오름차순)
  • sort(reverse=True) : 리스트의 요소를 큰 순서대로 정렬(내림차순)
>>> a = [10, 20, 30, 15, 20, 40]
>>> a.sort()
>>> a
[10, 15, 20, 20, 30, 40]

📎 참고) sort 메서드와 sorted 함수
파이썬은 리스트의 sort 메서드 뿐만 아니라 내장 함수 sorted도 제공한다.

  • sort : 정렬해주는 함수, 메서드를 사용한 리스트를 변경
  • sorted : 정렬해주는 함수, 정렬된 새 리스트를 생성
# sort
>> a = [10, 20, 30, 15, 20, 40]
>> a.sort()    # a의 내용을 변경하여 정렬
>> a
[10, 15, 20, 20, 30, 40]
# sorted
>> b = [10, 20, 30, 15, 20, 40]
>> sorted(b)    # 정렬된 새 리스트를 생성
[10, 15, 20, 20, 30, 40]

22.1.7 리스트의 모든 요소 삭제하기

  • clear() : 리스트의 모든 요소를 삭제한다.
  • clear 대신 del a[:]와 같이 시작, 끝 인덱스를 생략해 삭제할 수도 있다.
# clear 사용
>>> a = [10, 20, 30]
>>> a.clear()
>>> a
[]

# del a[:] 사용
>>> a = [10, 20, 30]
>>> del a[:]
>>> a
[]

22.1.8 리스트를 슬라이스로 조작하기

  • a[len(a):] : 리스트 끝에 값을 추가
  • 시작 인덱스를 len(a)로 지정해서 리스트의 마지막 인덱스보다 1이 더 큰 상태. 즉, 리스트 끝에서 시작하겠다는 의미
  • 요소 여러 개가 들어있는 리스트를 할당하면 리스트 끝에 할당한 리스트가 연결된다.
# 리스트 끝에 요소 하나의 리스트 추가
>>> a = [10, 20, 30]
>>> a[len(a):] = [500] # 값이 한 개 들어있는 리스트 추가
>>> a
[10, 20, 30, 500]

# 리스트 끝에 요소 여러 개의 리스트 하나 추가
>>> a = [10, 20, 30]
>>> a[len(a):] = [500, 600]
>>> a
[10, 20, 30, 500, 600]

📎 참고) 리스트가 비어 있는지 확인하기
len함수if조건문으로 확인 가능

if not len(seq):    # 리스트가 비어 있으면 True
if len(seq):        # 리스트에 요소가 있으면 True
# 리스트(시퀀스 객체)를 바로 `if`조건문으로 판단하는 방법 권장
if not seq:    # 리스트가 비어 있으면 True
if seq:        # 리스트에 내용이 있으면 True
# 마지막 요소에 접근해서 확인
>> seq = [10, 20, 30]
>> seq[-1]
30
# 비어있으면 에러 발생
>> a = []
>> a[-1]
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    a[-1]
IndexError: list index out of range
# 리스트에 요소가 있을 때만 마지막 요소 가져오기
seq = []
if seq:               # 리스트에 요소가 있는지 확인
    print(seq[-1])    # 요소가 있을 때만 마지막 요소를 가져옴

22.2 리스트의 할당과 복사 알아보기

# 리스트 a를 만든 뒤 b에 할당
>>> a = [0, 0, 0, 0, 0]
>>> b = a  # 리스트는 2개가 아닌 1개 생성 🔎

# a와 b 객체 확인
>>> a is b
True  # 변수이름만 다를 뿐 서로 같은 객체

# 리스트 요소 변경
>>> b[2] = 99  # 리스트 b의 요소 변경
>>> a
[0, 0, 99, 0, 0]  # a와 b에 모두 반영
>>> b
[0, 0, 99, 0, 0]

리스트 a와 b를 완전히 나눠 2개의 리스트로 만들려면 copy메서드 사용

>>> a = [0, 0, 0, 0, 0]
>>> b = a.copy()  # a의 요소가 모두 b에 복사

# a와 b 객체 확인
>>> a is b
False  # a와 b는 서로 다른 객체
>>> a == b 
True  # 복사되어 요소는 동일

# 리스트 요소 변경
>>> b[2] = 99
>>> a 
[0, 0, 0, 0, 0]  # 영향을 미치지 않음
>>> b
[0, 0, 99, 0, 0]

22.3 반복문으로 리스트의 요소를 모두 출력하기

22.3.1 for반복문으로 요소 출력하기

in 뒤에 리스트를 지정

>>> a = [38, 21, 53, 62, 19]
>>> for i in a:  # in 다음에 리스트를 직접 지정해도 무방 
        print(i)

# 실행결과
38
21
53
62
19

22.3.2 인덱스와 요소를 함께 출력

for 인덱스, 요소 in enumerate : for반복문으로 요소 출력 시 인덱스도 함께 출력
for 인덱스, 요소 in enumerate(리스트, start=숫자) : 시작 인덱스 지정 가능

>>> a = [38, 21, 53, 62, 19]
>>> for index, value in enumerate(a):
        print(index, value)  # 인덱스 0부터

# 실행결과
0 38
1 21
2 53
3 62
4 19

# 인덱스 0이 아닌 1부터 시작
>>> for index, value in enumerate(a):
        print(index + 1, value)

# 실행결과
1 38
2 21
3 53
4 62
5 19

# for 인덱스, 요소 in enumerate(리스트, start=숫자)
>>> for index, value in enumerate(a, start=1):
        print(index, value)

# 실행결과
1 38  # 인덱스 1부터 시작
2 21
3 53
4 62
5 19

📎 참고) for반복문에서 인덱스로 요소 출력
range에 len으로 리스트의 길이(요소 개수)를 구해 넣어주면 인덱스 순서대로 만들어진다. 따라서 리스트에 인덱스를 지정해 값을 가져올 수 있게 된다.

>> a = [38, 21, 53, 62, 19]
>> for i in range(len(a)):
         print(a[i])  # 인덱스로 지정
# 실행결과
38
21
53
62
19

22.3.3 while반복문으로 요소 출력하기

>>> a = [38, 21, 53, 62, 19]
>>> i = 0  # 변수 i를 인덱스로 활용
>>> while i < len(a):  # i <= len(a)를 사용할 경우 리스트 범위를 벗어난다.(에러발생)
         print(a[i])
         i += 1

# 실행결과
38
21
53
62
19

22.4 리스트의 가장 작은 수, 가장 큰 수, 합계 구하기

22.4.1 가장 작은 수와 가장 큰 수 구하기

1. for반복문으로 가장 작은 수, 큰 수 찾기

# 반복문을 통해 가장 작은 수
>>> a = [38, 21, 53, 62, 19]
>>> smallest = a[<0]
>>> for i in a:
        if i < smallest:
            smallest = i

>>> smallest
19

# 반복문을 통해 가장 큰 수 찾기
>>> a = [38, 21, 53, 62, 19]
>>> largest = a[0]
>>> for i in a:
        if i > largest:  # 부등호만 바꾸면 됨
            largest = i
 
>>> largest
62

2. sort메서드로 가장 작은 수, 큰 수 찾기

# 올림차순 정렬
>>> a = [38, 21, 53, 62, 19]
>>> a.sort()
>>> a[0]
19

# 내림차순 정렬
>>> a.sort(reverse=True)
>>> a[0]
62

3. min, max 함수로 가장 작은 수, 큰 수 찾기

>>> a = [38, 21, 53, 62, 19]
>>> min(a)  # 최솟값
19
>>> max(a)  # 최댓값
62

22.4.2 요소의 합계 구하기

1. for반복문으로 요소 합계 구하기

>>> a = [10, 10, 10, 10, 10]
>>> x = 0
>>> for i in a:
        x += i
 
>>> x
50

2. sum함수로 요소 합계 구하기

>>> a = [10, 10, 10, 10, 10]
>>> sum(a)
50

min, max, sum 함수에는 모든 반복 가능한 객체(iterable)(리스트, 튜플, 딕셔너리, 세트, range 등)를 넣을 수 있다.

22.5 리스트 표현식 사용하기

리스트 컴프리헨션(리스트 표현식)(list comprehension) : 리스트 안에 식, for 반복문, if 조건문 등을 지정하여 리스트를 생성하는 것

  • [식 for 변수 in 리스트]
    • 변수i부분을 다른 값과 연산하면 각 연산 결과를 리스트로 생성
  • list(식 for 변수 in 리스트)
# [식 for 변수 in 리스트]
>>> a = [i for i in range(10)]  # 0부터 9까지 숫자를 생성하여 리스트 생성
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# 변수 i 부분 연산 삽입
>>> c = [i + 5 for i in range(10)]  # 0부터 9까지 숫자를 생성하면서 값에 5를 더하여 리스트 생성
>>> c
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
>>> d = [i * 2 for i in range(10)]  # 0부터 9까지 숫자를 생성하면서 값에 2를 곱하여 리스트 생성
>>> d
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

# list(식 for 변수 in 리스트)
>>> b = list(i for i in range(10))  # 0부터 9까지 숫자를 생성하여 리스트 생성
>>> b
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

📎 참고) 대괄호와 list() 리스트 표현식
리스트 표현식은 대괄호([]), 리스트 둘 다 사용 가능하나 대괄효 방식이 파이썬 다운 코드이므로 대괄호([]) 형식을 권장한다.

  • 대괄호 형식 : [식 for 변수 in 리스트]
  • list : list(식 for 변수 in 리스트)

22.5.1 리스트 표현식에서 if조건문 사용하기

  • [식 for 변수 in 리스트 if 조건식]
  • list(식 for 변수 in 리스트 if 조건식)
  • 식(i)을 다른값과 연산해서 리스트를 만들어도 된다.
# [식 for 변수 in 리스트 if 조건식]
>>> a = [i for i in range(10) if i % 2 == 0]  
# 0~9 숫자 중 2의 배수인 숫자(짝수)로 리스트 생성
>>> a
[0, 2, 4, 6, 8]

# i를 다른 값과 연산하여 리스트 생성
>>> b = [i+5 for i in range(10) if i % 2 == 1]    # 0~9 숫자 중 홀수에 5를 더하여 리스트 생성
>>> b
[6, 8, 10, 12, 14]

22.5.2 for반복문과 if조건문을 여러 번 사용하기

리스트 표현식은 for와 if를 여러 번 사용할 수도 있다.

[for 변수1 in 리스트1 if 조건식1     for 변수2 in 리스트2 if 조건식2     ...     for 변수n in 리스트n if 조건식n]
 
list(for 변수1 in 리스트1 if 조건식1         for 변수2 in 리스트2 if 조건식2         ...         for 변수n in 리스트n if 조건식n)

# 2단부터 9단까지 구구단 리스트 생성
```python
>>> a = [i * j for j in range(2, 10) for i in range(1, 10)]
>>> a
[2, 4, 6, 8, 10, 12, 14, 16, 18, 3, 6, 9, 12, 15,
18, 21, 24, 27, 4, 8, 12, 16, 20, 24, 28, 32, 36,
5, 10, 15, 20, 25, 30, 35, 40, 45, 6, 12, 18, 24,
30, 36, 42, 48, 54, 7, 14, 21, 28, 35, 42, 49, 56,
63, 8, 16, 24, 32, 40, 48, 56, 64, 72, 9, 18, 27, 
36, 45, 54, 63, 72, 81]

# 코드 여러 줄로 입력
a = [i * j for j in range(2, 10)
           for i in range(1, 10)]

리스트 표현식에 for가 여러 개일 때 처리 순서는 뒤 → 앞

22.6 리스트에 map사용하기

map : 리스트의 요소를 지정된 함수로 처리해주는 함수
(map은 원본 리스트를 변경하지 않고 새 리스트를 생성한다.)
리스트 뿐만 아니라 모든 반복 가능한 객체를 넣을 수 있다.

  • list(map(함수, 리스트))
  • tuple(map(함수, 튜플))
    실수가 저장된 리스트가 있을 때 이 리스트의 모든 요소를 정수로 변환
>>> a = [1.2, 2.5, 3.7, 4.6]
>>> for i in range(len(a)):
        a[i] = int(a[i])
 
>>> a
[1, 2, 3, 4]

for 반복문으로 반복하면서 요소 변환, 번거로움

map을 사용해 편리하게 나타낼 수 있다.

>>> a = [1.2, 2.5, 3.7, 4.6]
>>> a = list(map(int, a))
>>> a
[1, 2, 3, 4]

22.6.1 input(), split()과 map

input(), split()의 결과가 문자열 리스트이기 때문에 map을 사용할 수 있다.

>>> a = input().split()
10 20 (입력)
>>> a
['10', '20']  # 실행결과 문자열 리스트로 출력

map을 사용해 정수로 변환

>>> a = map(int, input().split())
10 20 (입력)
>>> a
<map object at 0x03DFB0D0>
>>> list(a)
[10, 20]

# 위 리스트를 변수 두 개에 저장하면 a, b = map(int, input().split())와 같은 동작이 된다
>>> a, b = [10, 20]
>>> a
10
>>> b
20

map이 반환하는 맵 객체는 이터레이터라서 변수 여러 개에 저장하는 언패킹(unpacking)이 가능하다.
그래서 a, b = map(int, input().split())처럼 list를 생략한 것

a, b = map(int, input().split()) 코드 풀어쓰기

x = input().split()    # input().split()의 결과는 문자열 리스트
m = map(int, x)        # 리스트의 요소를 int로 변환, 결과는 맵 객체
a, b = m               # 맵 객체는 변수 여러 개에 저장할 수 있음

22.7 튜플 응용하기

튜플은 리스트와 달리 내용을 변경할 수 없다.(불변, immutable) 따라서 내용을 변경하는 append 같은 메서드는 사용할 수 없고, 요소의 정보를 구하는 메서드만 사용할 수 있다.

22.7.1 튜플에서 특정 값의 인덱스 구하기

index(값)

  • 튜플에서 특정 값의 인덱스를 구한다.
  • 같은 값이 여러 개일 경우 처음 찾은 인덱스를 구한다.(가장 작은 인덱스)
>>> a = (38, 21, 53, 62, 19, 53)
>>> a.index(53)
2

22.7.2 특정 값의 개수 구하기

count(값)

  • 튜플에서 특정 값의 개수를 구한다.
>>> a = (10, 20, 30, 15, 20, 40)
>>> a.count(20)  
2  # 20이 2개 들어있으므로 2가 출력

22.7.3 for반복문으로 요소 출력하기

for반복문으로 요소를 출력하는 방법은 리스트와 같다.

>>> a = (38, 21, 53, 62, 19)
>>> for i in a:
        print(i, end=' ')

# 실행결과
38 21 53 62 19

22.7.4 튜플 표현식 사용하기

튜플 표현식을 생성할 때는 tuple 안에 for 반복문과 if조건문을 지정한다.

  • tuple(식 for 변수ㅠ in 리스트 if 조건식)
>>> a = tuple(i for i in range(10) if i % 2 == 0)
>>> a
(0, 2, 4, 6, 8)

참고로 괄호(()) 안에 표현식을 넣으면 튜플이 아니라 제너레이터 표현식이 된다.

>>> (i for i in range(10) if i % 2 == 0)
<generator object <genexpr> at 0x050FE420>

22.7.5 tuple에 map 사용하기

튜플에 map을 사용하는 방법도 리스트와 같다.

>>> a = (1.2, 2.5, 3.7, 4.6)
>>> a = tuple(map(int, a))
>>> a
(1, 2, 3, 4)

22.7.6 tuple에서 가장 작은 수, 가장 큰 수, 합계 구하기

튜플도 min, max 함수로 가장 작은 수와 가장 큰 수를 구하고, sum함수로 요소의 합계를 구할 수 있다.

>>> a = (38, 21, 53, 62, 19)
>>> min(a)
19
>>> max(a)
62
>>> sum(a)
193

22.8 연습문제 : 리스트에서 특정 요소만 뽑아내기

다음 소스 코드를 완성하여 리스트 a에 들어있는 문자열 중에서 길이가 5인 것들만 리스트 형태로 출력되게 만드세요(리스트 표현식 사용).

# 문제
a = ['alpha', 'bravo', 'charlie', 'delta', 'echo', 'foxtrot', 'golf', 'hotel', 'india']
b = [___________________]
 
print(b)
# 실행결과
['alpha', 'bravo', 'delta', 'hotel', 'india']
# 정답
[i for i in a if len(i) == 5]
  1. 리스트 a에서 길이가 5인 문자열만 리스트 b에 저장
  2. b = []와 같이 되어 있으므로 리스트 표현식으로 b를 만든다.
  3. 대괄호([]) 안에 i for i in a if len(i) == 5를 넣어서 a에 들어있는 문자열을 모두 꺼낸 뒤 if조건문으로 길이가 5인 문자열을 뽑아낸다.
profile
안녕하세요 :-) 잘 부탁드립니다!

0개의 댓글