profile image

L o a d i n g . . .

unit 22. 리스트와 튜플 응용하기

 

  • 리스트 조작하기

리스트는 메서드(method)를 통해 조작할 수 있다.

메서드(method)란? 객체에 속한 함수를 뜻한다.

 

* 리스트에 요소 추가하기

- append: 요소 하나를 추가

- extend: 리스트를 연결하여 확장

- insert: 특정 인덱스에 요소 추가

 

append(요소)는 리스트 끝에 요소 하나를 추가한다.

>>> a = [10, 20, 30]
>>> a.append(500)
>>> a
[10, 20, 30, 500]
>>> len(a)
4

 

append append(리스트)처럼 리스트를 넣으면 리스트 안에 리스트가 들어간다.

>>> a = [10, 20, 30]
>>> a.append([500, 600])
>>> a
[10, 20, 30, [500, 600]]
>>> len(a)
4

a.append([500, 600]) [500, 600]이라는 요소 하나를 리스트 a 끝에 추가하는 것이다.

따라서 리스트 a len으로 길이를 구해보면 5가 아닌 4가 나온다.

 

 

extend(리스트)는 리스트 끝에 다른 리스트를 연결하여 리스트를 확장한다.

리스트에 요소를 여러 개 추가할 때는 extend를 사용한다.

>>> a = [10, 20, 30]
>>> a.extend([500, 600])
>>> a
[10, 20, 30, 500, 600]
>>> len(a)
5

이때 메서드를 호출한 리스트가 변경되며 새 리스트는 생성되지 않는다.

 

 

insert(인덱스, 요소)는 리스트의 특정 인덱스에 요소 하나를 추가한다.

>>> a = [10, 20, 30]
>>> a.insert(2, 500)
>>> a
[10, 20, 500, 30]
>>> len(a)
4

insert에서 자주 사용하는 패턴은 다음 2가지이다.

- insert(0, 요소): 리스트의 맨 처음에 요소를 추가

- insert(len(리스트), 요소): 리스트 끝에 요소를 추가

 

 

* 리스트에서 요소 삭제하기

다음과 같이 요소를 삭제하는 메서드는 2가지가 있다.

- pop: 마지막 요소 또는 특정 인덱스의 요소를 삭제

- remove: 특정 값을 찾아서 삭제

 

pop()은 리스트의 마지막 요소를 삭제한 뒤 삭제한 요소를 반환한다.

>>> a = [10, 20, 30]
>>> a.pop()
30
>>> a
[10, 20]

원하는 인덱스의 요소를 삭제하고 싶을 땐 pop에 인덱스를 지정하면 된다.

pop(인덱스)는 해당 인덱스의 요소를 삭제한 뒤 삭제한 요소를 반환한다.

+ pop 대신 del을 사용해도 상관없다.

 

 

remove(값)은 리스트에서 특정 값을 찾아서 삭제한다.

>>> a = [10, 20, 30]
>>> a.remove(20)
>>> a
[10, 30]

만약 리스트에 같은 값이 여러 개 있을 경우 처음 찾은 값을 삭제한다.

 

 

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

index(값)은 리스트에서 특정 값의 인덱스를 구한다.

>>> a = [10, 20, 30, 15, 20, 40]
>>> a.index(20)
1

이때 같은 값이 여러 개일 경우 처음 찾은 인덱스를 구한다.(가장 작은 인덱스)

 

 

* 특정 값의 개수 구하기

count(값)은 리스트에서 특정 값의 개수를 구한다.

>>> a = [10, 20, 30, 15, 20, 40]
>>> a.count(20)
2

 

* 리스트의 순서 뒤집기

reverse()는 리스트에서 요소의 순서를 반대로 뒤집는다.

>>> a = [10, 20, 30, 15, 20, 40]
>>> a.reverse()
>>> a
[40, 20, 15, 30, 20, 10]

 

* 리스트의 요소를 정렬하기

sort()는 리스트의 요소을 작은 순서대로 정렬합니다(오름차순). 

>>> a = [10, 20, 30, 15, 20, 40]
>>> a.sort()
>>> a
[10, 15, 20, 20, 30, 40]

sort(reverse=True): 리스트의 값을 큰 순서대로 정렬(내림차순)

 

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

>>> a = [10, 20, 30]
>>> a.clear()
>>> a
[]

 

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

다음과 같이 메소드 대신 슬라이스로 리스트를 조작할 수 있다. 

여기서 a[len(a):] = [500, 600]은 a.extend([500, 600])과 같다.

>>> a = [10, 20, 30]
>>> a[len(a):] = [500, 600]
>>> a
[10, 20, 30, 500, 600]

 

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

더보기

할당과 복사는 비슷한 것 같지만 큰 차이점이 있다.

먼저 다음과 같이 리스트를 만든 뒤 다른 변수에 할당한다.

>>> a = [0, 0, 0, 0, 0]
>>> b = a

b = a와 같이 리스트를 다른 변수에 할당하면 리스트는 두 개가 될 것 같지만 실제로는 리스트가 한 개이다.

a b is 연산자로 비교해보면 True가 나온다. 즉, 변수 이름만 다를 뿐 리스트 a와 b는 같은 객체이다.

따라서 b[2] = 99와 같이 리스트 b의 요소를 변경하면 리스트 a b에 모두 반영된다.

>>> b[2] = 99
>>> a
[0, 0, 99, 0, 0]
>>> b
[0, 0, 99, 0, 0]

 

a b를 완전히 다른 두 개로 만들려면 copy 메서드로 모든 요소를 복사해야 한다.

>>> a = [0, 0, 0, 0, 0]
>>> b = a.copy()

b = a.copy()와 같이 copy를 사용한 뒤 b에 할당해주면 리스트 a의 요소가 모두 b에 복사된다.

a b is 연산자로 비교해보면 False가 나온다. 즉, 두 리스트는 다른 객체인 것이다.

>>> a is b
False
>>> a == b
True

 

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

더보기

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

for 반복문은 그냥 in 뒤에 리스트를 지정하면 된다.

>>> a = [38, 21, 53, 62, 19]
>>> for i in a:
...     print(i)
...
38
21
53
62
19

for i in a:는 리스트 a에서 요소를 꺼내서 i에 저장하고, 꺼낼 때마다 코드를 반복한다. 따라서 print i를 출력하면 모든 요소를 순서대로 출력할 수 있다.

 

* 인덱스와 요소를 함께 출력하기

for 반복문으로 요소를 출력할 때 인덱스도 함께 출력할 때는 enumerate를 사용한다.

 

- for 인덱스, 요소 in enumerate(리스트):

>>> a = [38, 21, 53, 62, 19]
>>> for index, value in enumerate(a):
...     print(index, value)
...
0 38
1 21
2 53
3 62
4 19

for index, value in enumerate(a):와 같이 enumerate에 리스트를 넣으면 for 반복문에서 인덱스와 요소를 동시에 꺼내 올 수 있다.

이때 만약 인덱스를 1부터 출력하고 싶다면, 다음과 같이 enumerate start를 지정해주면 된다.

- for 인덱스, 요소 in enumerate(리스트, start=숫자):

>>> for index, value in enumerate(a, start=1):
...     print(index, value)
...
1 38
2 21
3 53
4 62
5 19

 

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

>>> a = [38, 21, 53, 62, 19]
>>> i = 0
>>> while i < len(a):
...     print(a[i])
...     i += 1
...
38
21
53
62
19

while 반복문으로 리스트의 요소를 출력할 때는 변수 i를 인덱스로 활용한다.

 

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

더보기

for문과 if문을 이용해 리스트에서 가장 작은 수와 큰 수를 구할 수 있다.

>>> a = [38, 21, 53, 62, 19]
>>> smallest = a[0]
>>> for i in a:
...     if i < smallest:
...         smallest = i
...
>>> smallest
19

먼저 리스트 a의 첫 번째 요소 a[0]를 변수 smallest에 저장한다. 그리고 for로 리스트의 요소를 모두 반복하면서 i smallest보다 작으면 smallest i를 할당한다.

즉, 숫자를 계속 비교해서 숫자가 작으면 smallest를 바꾸는 방식이다.

 

가장 큰 수는 부등호를 반대로 만들면 된다.

>>> a = [38, 21, 53, 62, 19]
>>> largest = a[0]
>>> for i in a:
...     if i > largest:
...         largest = i
...
>>> largest
62

마찬가지로 리스트의 숫자를 계속 비교해서 숫자가 크면 largest를 바꾸는 방식이다.

 

더 간단하게는 sort 메소드를 이용해 리스트의 가장 작은 수, 큰 수를 구할 수 있다.

>>> a = [38, 21, 53, 62, 19]
>>> a.sort()
>>> a[0]
19
>>> a.sort(reverse=True)
>>> a[0]
62

리스트를 작은 순서대로 정렬(오름차순)하면 첫 번째 요소가 가장 작은 수이며, 반대로 큰 순서대로 정렬(내림차순)하면 첫 번째 요소가 가장 큰 수가 됨을 이용한다.

 

더 간단하게는 파이썬에서 제공하는 min, max 함수를 사용하면 된다.

>>> a = [38, 21, 53, 62, 19]
>>> min(a)
19
>>> max(a)
62

 

* 요소의 합계 구하기

합계를 구할 때도 반복문을 사용하면 된다.

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

변수 x에 0을 할당하고, for 반복문으로 리스트의 요소를 모두 반복하면서 요소를 x에 계속 더해주면 된다. 단, 이때 x에는 반드시 0을 할당해야 한다.

+ 파이썬에서는 합계를 구하는 sum 함수를 제공한다.

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

 

※ 참고 : 여기서 설명한 min, max, sum에는 리스트뿐만 아니라 모든 반복 가능한 객체(iterable)를 넣을 수 있다.  반복 가능한 객체는 리스트, 튜플, 딕셔너리, 세트, range 등 여러 가지가 있다.

 

  • 리스트 표현식 사용하기

더보기

파이썬의 리스트가 특이한 점은 리스트 안에 for 반복문과 if 조건문을 사용할 수 있다는 것이다.

개념적으로 보면 "리스트 표현식"이라고 할 수 있다.

리스트 표현식은 다음과 같이 리스트 안에 식, for 반복문을 지정한다.

- [ for 변수 in 리스트]

- list( for 변수 in 리스트)

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

즉, range(10)으로 0부터 9까지 생성하여 변수 i에 숫자를 꺼내고, 최종적으로 i를 이용하여 리스트를 만든다는 뜻

 

[i for i in range(10)]는 변수 i를 그대로 사용하지만, 다음과 같이 식 부분에서 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]

식을 [i + 5 for i in range(10)]과 같이 i에 5를 더하면 0부터 9까지의 숫자에 5를 더한 값으로 리스트를 생성한다.

 

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

다음과 같이 if 조건문은 for 반복문 뒤에 지정한다.

- [식 for 변수 in 리스트 if 조건식]

- list(식 for 변수 in 리스트 if 조건식)

>>> a = [i for i in range(10) if i % 2 == 0]    # 0~9 숫자 중 2의 배수인 숫자(짝수)로 리스트 생성
>>> a
[0, 2, 4, 6, 8]

[i for i in range(10) if i % 2 == 0]는 0부터 9까지 숫자를 생성하여 2의 배수인 숫자(짝수)로만 리스트를 생성한다.즉, 다음과 같이 for 반복문 뒤에 if 조건문을 지정하면 숫자를 생성한 뒤 if 조건문에서 특정 숫자만 뽑아내서 리스트를 생성한다.

 

* 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단까지 구구단을 리스트 생성하는 코드이다.

>>> 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]

※ 리스트 표현식에 for가 여러 개일 때 처리 순서는 뒤에서 앞으로 순이다.

 

  • 리스트에 map 사용하기

더보기

map은 리스트의 요소를 지정된 함수로 처리해주는 함수이다. (참고로 map은 원본 리스트를 변경하지 않고 새 리스트를 생성합니다).

- list(map(함수, 리스트))

- tuple(map(함수, 튜플))

 

실수가 저장된 리스트가 있을 때 이 리스트의 모든 요소를 정수로 변환하려면 어떻게 해야 할까?

먼저 for 반복문을 사용해서 변환해보겠다.

>>> 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 range(len(a))를 사용해서 인덱스를 가져온다. 그리고 가져온 인덱스로 요소 하나 하나에 접근한 뒤 int로 변환하여 다시 저장해주면 된다.

다음과 map을 사용해 변환한 예이다.

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

a = list(map(int, a)) 한 줄로 변환이 끝난다. 

map int와 리스트를 넣으면 리스트의 모든 요소를 int를 사용해서 변환한다. 그다음에 list를 사용해서 map의 결과를 다시 리스트로 만들어준다.

 

 

* input().split()과 map

지금까지 input().split()으로 값을 여러 개 입력받고 정수, 실수로 변환할 때도 map을 사용했다.

사실 input().split()의 결과가 문자열 리스트라서 map을 사용할 수 있었다.

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

a, b = map(int, input().split())을 풀어서 쓰면 다음과 같은 코드가 된다.

 

  • 튜플 응용하기

더보기

튜플은 리스트와는 달리 내용을 변경할 수 없다(불변, immutable).

따라서 내용을 변경하는 append 같은 메서드는 사용할 수 없고, 요소의 정보를 구하는 메서드만 사용할 수 있다.

 

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

index(값)은 튜플에서 특정 값의 인덱스를 구한다.

이때 같은 값이 여러 개일 경우 처음 찾은 인덱스를 구한다(가장 작은 인덱스).

>>> a = (38, 21, 53, 62, 19, 53)
>>> a.index(53)
2

 

* 특정 값의 개수 구하기

count(값) 튜플에서 특정 값의 개수를 구한다.

>>> a = (10, 20, 30, 15, 20, 40)
>>> a.count(20)
2

 

* 반복문으로 요소 출력하기

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

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

 

* 튜플 표현식 사용하기

튜플을 리스트 표현식처럼 생성할 때는 다음과 같이 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)

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

 

* tuple에 map 사용하기

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

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

 

* 튜플에서 가장 작은 수, 가장 큰 수, 합계 구하기

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

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

 

 

 

unit 23. 2차원 리스트 사용하기

 

  • 2차원 리스트를 만들고 요소에 접근하기

더보기

2차원 리스트는 다음과 같이 가로×세로 형태로 이루어져 있으며, 행(row)과 열(column) 모두 0부터 시작한다.

2차원 리스트는 리스트 안에 리스트를 넣어서 만들 수 있으며 안쪽의 각 리스트는 ,(콤마)로 구분한다.

- 리스트 = [[값, 값], [값, 값], [값, 값]]

>>> a = [[10, 20], [30, 40], [50, 60]]
>>> a
[[10, 20], [30, 40], [50, 60]]

다음은 가로 2, 세로 3의 2차원 리스트이다. 가로, 세로를 알아보기 쉽게 세 줄로 입력해도 된다.

a = [[10, 20],
     [30, 40],
     [50, 60] ]

 

* 2차원 리스트의 요소에 접근하기

2차원 리스트의 요소에 접근하거나 값을 할당할 때는 리스트 뒤에 [ ](대괄호)를 두 번 사용하며

[ ] 안에 세로(row) 인덱스와 가로(column) 인덱스를 지정해주면 된다.

- 리스트[세로인덱스][가로인덱스]

- 리스트[세로인덱스][가로인덱스] = 값

>>> a = [[10, 20], [30, 40], [50, 60]]
>>> a[0] [0]            # 세로 인덱스 0, 가로 인덱스 0인 요소 출력
10
>>> a[1][1]           # 세로 인덱스 1, 가로 인덱스 1인 요소 출력
40
>>> a[2][1]           # 세로 인덱스 2, 가로 인덱스 0인 요소 출력
60
>>> a[0][1] = 1000    # 세로 인덱스 0, 가로 인덱스 1인 요소에 값 할당
>>> a[0][1]
1000

2차원 리스트도 인덱스는 0부터 시작한다. 따라서 리스트의 가로 첫 번째, 세로 첫 번째 요소는 a[0][0]이 된다.

 

  • 반복문으로 2차원 리스트의 요소를 모두 출력하기

더보기

* for 반복문을 한 번만 사용하기

다음은 for 반복문을 한 번만 사용하여 2차원 리스트의 요소를 모두 출력한 것이다.

>>> a = [[10, 20], [30, 40], [50, 60]]
>>> for x, y in a:    # 리스트의 가로 한 줄(안쪽 리스트)에서 요소 두 개를 꺼냄
...     print(x, y)
...
10 20
30 40
50 60

2차원 리스트에 for를 사용하면 가로 한 줄씩 반복하게 된다. 이때 for x, y in a:와 같이 in 앞에 변수를 두 개 지정해주면 가로 한 줄(안쪽 리스트)에서 요소 두 개를 꺼내 온다.

 

 

* for 반복문을 두 번 사용하기

다음은 for 반복문을 두 번 사용해서 2차원 리스트의 요소를 출력한 것이다.

a = [[10, 20], [30, 40], [50, 60]]
 
for i in a:        # a에서 안쪽 리스트를 꺼냄
    for j in i:    # 안쪽 리스트에서 요소를 하나씩 꺼냄
        print(j, end=' ')
    print()

실행 결과는 다음과 같다.

10 20
30 40
50 60

먼저 for i in a:는 전체 리스트에서 가로 한 줄씩 꺼내 온다. 그래서 다시 for j in i:와 같이 가로 한 줄(안쪽 리스트) i에서 요소를 하나씩 꺼내면 된다.

 

* for와 range 사용하기

for range에 세로 크기와 가로 크기를 지정해서 2차원 리스트의 요소를 인덱스로 접근할 수도 있다.

a = [[10, 20], [30, 40], [50, 60]]
 
for i in range(len(a)):            # 세로 크기
    for j in range(len(a[i])):     # 가로 크기
        print(a[i][j], end=' ')
    print()

실행 결과는 마찬가지로 위와 같다.

for i in range(len(a)):는 세로 크기 3만큼 반복하고, for j in range(len(a[i])):는 가로 크기 2만큼 반복한다.

+ 요소에 접근할 때는 리스트[세로인덱스][가로인덱스] 형식으로 접근해야 해서, 세로 인덱스에 변수 i를, 가로 인덱스에 변수 j를 지정해준다.

 

 

* while 반복문을 한 번 사용하기

다음은 while 반복문을 사용하여 2차원 리스트의 요소를 출력한 것이다.

a = [[10, 20], [30, 40], [50, 60]]
 
i = 0
while i < len(a):    # 반복할 때 리스트의 크기 활용(세로 크기)
    x, y = a[i]      # 요소 두 개를 한꺼번에 가져오기
    print(x, y)
    i += 1           # 인덱스를 1 증가시킴

while 반복문을 사용할 때도 리스트의 크기를 활용하면 편리하다.

 

 

* while 반복문을 두 번 사용하기

a = [[10, 20], [30, 40], [50, 60]]
 
i = 0
while i < len(a):           # 세로 크기
    j = 0
    while j < len(a[i]):    # 가로 크기
        print(a[i][j], end=' ')
        j += 1              # 가로 인덱스를 1 증가시킴
    print()
    i += 1                  # 세로 인덱스를 1 증가시킴

먼저 while i < len(a):와 같이 세로 크기만큼 반복하면서 while j < len(a[i]):와 같이 가로 크기(안쪽 리스트의 요소 개수)만큼 반복하면 된다.

이때 i += 1을 안쪽 while에서 수행하면 반복이 제대로 되지 않으므로 주의해야 할 것이다.

 

  • 반복문으로 리스트 만들기

더보기

* for 반복문으로 1차원 리스트 만들기

다음은 for문으로 요소 10개가 일렬로 늘어서 있는 1차원 리스트를 만든 것이다.

a = []    # 빈 리스트 생성
 
for i in range(10):
    a.append(0)    # append로 요소 추가
 
print(a)

 for 반복문으로 10번 반복하면서 append로 요소를 추가하면 1차원 리스트를 만들 수 있다.

 

 

* for 반복문으로 2차원 리스트 만들기

a = []    # 빈 리스트 생성
 
for i in range(3):
    line = []              # 안쪽 리스트로 사용할 빈 리스트 생성
    for j in range(2):
        line.append(0)     # 안쪽 리스트에 0 추가
    a.append(line)         # 전체 리스트에 안쪽 리스트를 추가
 
print(a)

실행 결과는 다음과 같다.

[[0, 0], [0, 0], [0, 0]]

먼저 세로 크기만큼 반복하면서 안쪽 리스트로 사용할 빈 리스트 line을 만든다. 그다음에 가로 크기만큼 반복하면서 line append로 0을 추가한다.

바깥쪽 반복문에서는 다시 append로 전체 리스트 a에 안쪽 리스트 line을 추가해주면 된다.

참고 : 여기서는 append에 리스트를 넣으면 리스트 안에 리스트가 들어가는 특성을 이용함.

 

 

* 리스트 표현식으로 2차원 리스트 만들기

리스트 표현식을 활용하면 코드 한 줄로 2차원 리스트를 만들 수 있다.

>>> a = [[0 for j in range(2)] for i in range(3)]
>>> a
[[0, 0], [0, 0], [0, 0]]

리스트 표현식 안에서 리스트 표현식을 사용했다.

먼저 [0 for j in range(2)]로 0을 2번 반복하여 [0, 0]으로 만들고 다시 for i in range(3)으로 [0, 0]을 3번 반복하여 [[0, 0], [0, 0], [0, 0]]으로 만든다.

 

※ 만약 for 반복문을 한 번만 사용하고 싶다면 다음과 같이 식 부분에서 리스트 자체를 곱해주면 된다.

>>> a = [[0] * 2 for i in range(3)]
>>> a
[[0, 0], [0, 0], [0, 0]]

 

* 톱니형 리스트 만들기

톱니형 리스트(jagged list)는 가로 크기가 불규칙한 리스트를 뜻하며, 다음과 같이 만들 수 있다.

a = [3, 1, 3, 2, 5]    # 가로 크기를 저장한 리스트
b = []    # 빈 리스트 생성
 
for i in a:      # 가로 크기를 저장한 리스트로 반복
    line = []    # 안쪽 리스트로 사용할 빈 리스트 생성
    for j in range(i):    # 리스트 a에 저장된 가로 크기만큼 반복
        line.append(0)
    b.append(line)        # 리스트 b에 안쪽 리스트를 추가
 
print(b)

실행 결과는 다음과 같다. 

[[0, 0, 0], [0], [0, 0, 0], [0, 0], [0, 0, 0, 0, 0]]

먼저 리스트 a에 톱니형 리스트의 가로 크기를 미리 저장해 놓는다. 이 리스트 a for로 반복하면 가로 크기를 꺼내면서 5번 반복하게 된다.

for 반복문 안에서 다시 for로 꺼낸 가로 크기 i만큼 반복하면서 append로 요소를 추가해준다. 그리고 바깥쪽 반복문에서 리스트 b에 안쪽 리스트 line을 추가하면 된다.

 

  • 2차원 리스트의 할당과 복사 알아보기

더보기

다음과 같이 2차원 리스트를 만든 뒤 다른 변수에 할당하고, 요소를 변경해보면 두 리스트에 모두 반영된다.

>>> a = [[10, 20], [30, 40]]
>>> b = a
>>> b[0][0] = 500
>>> a
[[500, 20], [30, 40]]
>>> b
[[500, 20], [30, 40]]

 

만약 완전히 다른 2차원 리스트를 만들고 싶을 땐 '복사'를 해야한다.

그리고 2차원 이상의 다차원 리스트는 리스트를 완전히 복사하려면 copy 메서드 대신 copy 모듈의 deepcopy 함수를 사용한다.

>>> a = [[10, 20], [30, 40]]
>>> import copy             # copy 모듈을 가져옴
>>> b = copy.deepcopy(a)    # copy.deepcopy 함수를 사용하여 깊은 복사
>>> b[0][0] = 500
>>> a
[[10, 20], [30, 40]]
>>> b
[[500, 20], [30, 40]]

 

할당과 달리 copy 모듈의 deepcopy 함수를 쓰면 리스트 b의 요소를 변경해도 리스트 a에는 영향을 미치지 않는다. 

copy.deepcopy 함수는 중첩된 리스트(튜플)에 들어있는 모든 리스트(튜플)를 복사하는 깊은 복사(deep copy)를 해준다.

 

 

 

unit 22. 문자열 응용하기

 

  • 문자열 조작하기

더보기

문자열은 문자열을 조작하거나 정보를 얻는 다양한 메서드(method)를 제공한다.

* 문자열 바꾸기

replace('바꿀문자열', '새문자열')은 문자열 안의 문자열을 다른 문자열로 바꾼다.

>>> s = 'Hello, world!'
>>> s = s.replace('world!', 'Python')
>>> s
'Hello, Python'

만약 바뀐 결과를 유지하고 싶다면 문자열이 저장된 변수에 replace를 사용한 뒤 다시 변수에 할당해주면 된다.

 

* 문자 바꾸기

translate는 문자열 안의 문자를 다른 문자로 바꾼다.

>>> table = str.maketrans('aeiou', '12345')
>>> 'apple'.translate(table)
'1ppl2'

먼저 str.maketrans('바꿀문자', '새문자')로 변환 테이블을 만든다. 그다음에 translate(테이블)을 사용하면 문자를 바꾼 뒤 결과를 반환한다.

 

* 문자열 분리하기

split()은 공백을 기준으로 문자열을 분리하여 리스트로 만든다.

>>> 'apple pear grape pineapple orange'.split()
['apple', 'pear', 'grape', 'pineapple', 'orange']

지금까지 input으로 문자열을 입력받은 뒤 리스트로 만든 메서드가 바로 이 split이다.

 

* 구분자 문자열과 문자열 리스트 연결하기

join(리스트)구분자 문자열과 문자열 리스트의 요소를 연결하여 문자열로 만든다.

>>> ' '.join(['apple', 'pear', 'grape', 'pineapple', 'orange'])
'apple pear grape pineapple orange'

다음은 공백 ' ' join을 사용하여 각 문자열 사이에 공백이 들어가도록 만든 것이다.

 

* 소문자 대문자 변환

upper()는 문자열의 문자를 모두 대문자로, lower()는 문자열의 문자를 모두 소문자로 바꿔준다.

>>> 'python'.upper()
'PYTHON'
>>> 'PYTHON'.lower()
'python'

 

* 공백 삭제하기

lstrip() : 문자열에서 왼쪽에 있는 연속된 모든 공백을 삭제

rstrip() : 문자열에서 오른쪽에 있는 연속된 모든 공백을 삭제

strip() : 문자열에서 양쪽에 있는 연속된 모든 공백을 삭제

>>> '   Python   '.lstrip()
'Python   '
>>> '   Python   '.rstrip()
'   Python'
>> '   Python   '.strip()
'Python'

 

* 특정 문자 삭제하기

lstrip('삭제할문자들') : 삭제할 문자들을 문자열 형태로 넣어주면 문자열 왼쪽에 있는 해당 문자를 삭제

rstrip('삭제할문자들')문자열 오른쪽에 있는 해당 문자를 삭제

strip('삭제할문자들') : 문자열 양쪽에 있는 해당 문자를 삭제

>>> ', python.'.lstrip(',.')
' python.'
>>> ', python.'.rstrip(',.')
', python'
>>> ', python.'.strip(',.')
' python'

 

* 정렬하기

ljust(길이) : 문자열을 지정된 길이로 만든 뒤 왼쪽으로 정렬하며 남는 공간을 공백으로 채움.

rjust(길이) : 오른쪽으로 정렬하며 남는 공간을 공백으로 채움.

center(길이) : 가운데로 정렬하며 남는 공간을 공백으로 채움.

 

다음은 문자열 'python'의 길이를 10으로 만든 뒤 가운데로 정렬하고 양 옆의 남는 공간을 공백 2칸씩 채운 것.

>>> 'python'.center(10)
'  python  '

 

* 메서드 체이닝

문자열 메서드는 처리한 결과를 반환하도록 만들어져 있다.

따라서 메서드를 계속 연결해서 호출하는 메서드 체이닝이 가능하다. 

 

다음은 문자열을 오른쪽으로 정렬한 뒤 대문자로 바꾼다.

>>> 'python'.rjust(10).upper()
'    PYTHON'

 

* 문자열 왼쪽에 0 채우기

zfill(길이)는 지정된 길이에 맞춰서 문자열의 왼쪽에 0을 채운다.

>>> '35'.zfill(4)        # 숫자 앞에 0을 채움
'0035'
>>> '3.5'.zfill(6)       # 숫자 앞에 0을 채움
'0003.5'
>>> 'hello'.zfill(10)    # 문자열 앞에 0을 채울 수도 있음
'00000hello'

 

*문자열 찾기

find('찾을문자열')문자열에서 특정 문자열을 찾아서 인덱스를 반환하고, 문자열이 없으면 -1을 반환한다.

>>> 'apple pineapple'.find('pl')
2
>>> 'apple pineapple'.find('xy')
-1

rfind('찾을문자열')은 오른쪽에서부터 특정 문자열을 찾아서 인덱스를 반환하고, 문자열이 없으면 -1을 반환한다.

find, rfind 이외에도 index, rindex로 문자열의 위치를 찾을 수 있다.

 

index('찾을문자열')은 왼쪽에서부터 특정 문자열을 찾아서 인덱스를 반환한다. 단, find와 달리 문자열이 없으면 에러를 발생시킨다.

>>> 'apple pineapple'.index('pl')
2

rindex('찾을문자열')은 오른쪽에서부터 특정 문자열을 찾아서 인덱스를 반환한다.

 

* 문자열 개수 세기

count('문자열')은 현재 문자열에서 특정 문자열이 몇 번 나오는지 알아낸다.

>>> 'apple pineapple'.count('pl')
2

 

  • 문자열 서식지정자와 포매팅 사용하기

더보기

문자열 안에서 특정 부분을 원하는 값으로 바꿀 때 서식 지정자 또는 문자열 포매팅을 사용한다.

1) 서식 지정자 사용하기

- '%s' % '문자열'

>>> 'I am %s.' % 'james'
'I am james.'

서식 지정자는 %로 시작하고 자료형을 뜻하는 문자가 붙는다. %s는 문자열이라는 뜻이며 string의 s이다. 이처럼 문자열 안에 %s를 넣고 그 뒤에 %를 붙인 뒤 'james'를 지정해주면 %s 부분이 'james'로 바뀐다.

 

- '%d' % 숫자

>>> 'I am %d years old.' % 20
'I am 20 years old.'

숫자는 %d를 넣고 % 뒤에 숫자를 지정하면 된다.

 - '%f' % 숫자

>>> '%f' % 2.3
'2.300000'

실수를 넣을 때는 %f를 사용하며 고정 소수점 fixed point의 f이다.

 

- '%.자릿수f' % 숫자

>>> '%.2f' % 2.3
'2.30'
>>> '%.3f' % 2.3
'2.300'

소수점 이하 자릿수를 지정하고 싶다면 다음과 같이 f 앞에 .(점)과 자릿수를 지정해주면 된다.

 

 * 서식 지정자로 문자열 정렬하기

% 뒤에 숫자를 붙이면 문자열을 지정된 길이로 만든 뒤 오른쪽으로 정렬하고 남는 공간을 공백으로 채운다.

- %길이s

>>> '%10s' % 'python'
'    python'

왼쪽 정렬은 다음과 같이 문자열 길이에 -를 붙여주면 된다.

- %-길이s

 

* 서식 지정자로 문자열 안에 값 여러 개 넣기

문자열 안에 값을 두 개 이상 넣으려면 %를 붙이고, 괄호 안에 값(변수)을 콤마로 구분해서 넣어주면 된다.

- '%d %s' % (숫자, '문자열')

>>> 'Today is %d %s.' % (3, 'April')
'Today is 3 April.'

 이처럼 서식 지정자가 여러 개면 괄호 안의 값(변수) 개수도 서식 지정자 개수와 똑같이 맞춰주어야 한다.

 

2) format 메서드 사용하기

파이썬은 문자열을 만들 때 서식 지정자 방식보다 더 간단한 문자열 포매팅(string formatting)을 제공한다.

문자열 포매팅은 { }(중괄호) 안에 포매팅을 지정하고 format 메서드로 값을 넣는다.

 

- '{인덱스}'.format(값)

>>> 'Hello, {0}'.format('world!')
'Hello, world!'
>>> 'Hello, {0}'.format(100)
'Hello, 100'

다음은 값을 여러 개 넣어보았을 때이다. 

>>> 'Hello, {0} {2} {1}'.format('Python', 'Script', 3.6)
'Hello, Python 3.6 Script'

+ 같은 인덱스가 지정된 { }를 여러 개 넣으면 같은 값이 여러 개 들어간다.

+ 만약 { }에서 인덱스를 생략하면 format에 지정한 순서대로 값이 들어간다.

 

 

* format 메서드로 문자열 정렬하기

문자열 포매팅도 문자열을 정렬할 수 있다.

다음과 같이 인덱스 뒤에 :(콜론)을 붙이고 정렬할 방향과 길이를 지정해주면 된다.

- '{인덱스:<길이}'.format(값)

>>> '{0:<10}'.format('python')
'python    '

그러면 문자열을 지정된 길이로 만든 뒤 왼쪽으로 정렬하고 남는 공간을 공백으로 채운다.

 

* 숫자 개수 채우기

%d는 다음과 같이 % d 사이에 0과 숫자 개수를 넣어주면 자릿수에 맞춰서 앞에 0이 들어간다.

- '%0개수d' % 숫자

- '{인덱스:0개수d'}'.format(숫자)

>>> '%03d' % 1
'001'
>>> '{0:03d}'.format(35)
'035'

물론 실수도 숫자 개수를 맞출 수 있다. 특히 소수점 이하 자릿수를 지정하고 싶으면 %08.2f처럼 .(점) 뒤에 자릿수를 지정해주면 된다.

- '%0개수.자릿수f' % 숫자

- '{인덱스:0개수.자릿수f'}.format(숫자)

 

* 채우기와 정렬을 조합해서 사용하기

문자열 포매팅은 채우기와 정렬을 조합해서 사용할 수 있다.

다음과 같이 { }에 인덱스, 채우기, 정렬, 길이, 자릿수, 자료형 순으로 지정해준다.

- '{인덱스:[[채우기]정렬][길이][.자릿수][자료형]}'

 

다음은 길이를 10으로 만든 뒤 왼쪽, 오른쪽으로 정렬하고 남는 공간은 0으로 채운다.

>>> '{0:0<10}'.format(15)    # 길이 10, 왼쪽으로 정렬하고 남는 공간은 0으로 채움
'1500000000'
>>> '{0:0>10}'.format(15)    # 길이 10, 오른쪽으로 정렬하고 남는 공간은 0으로 채움
'0000000015'

물론 실수로 만들고 싶다면 소수점 자릿수와 실수 자료형 f를 지정해주면 된다.

 

3) 문자열 포매팅에 변수를 그대로 사용하기

파이썬 3.6부터는 문자열을 만드는 더 간단한 방법을 제공한다.

다음과 같이 변수에 값을 넣고 { }에 변수 이름을 지정하면 된다.

이때는 문자열 앞에 포매팅(formatting)이라는 뜻으로 f를 붙인다.

>>> language = 'Python'
>>> version = 3.6
>>> f'Hello, {language} {version}'
'Hello, Python 3.6'
복사했습니다!