파이썬 | 리스트 나머지 내용

CHOI·2021년 10월 30일
0

Python

목록 보기
15/33
post-thumbnail

3. 반복문으로 리스트 요소 출력

리스트의 인덱스를 지정하여 요소를 한 개씩 출력하기 상당히 귀찮다. 이번에는 리스트에 반복문을 사용하여 간단하게 모든 요소를 출력해보자

3-1 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) 를 하여 모든 요소들을 출력할 수 있다.

물론 in 다음에 리스트를 직접 넣어도 상관없다.

for i in [38, 21, 53, 62, 19]:
	print(i)

인덱스와 요소를 함께 출력 ( enumerate )

for 반복문으로 요소를 출력할 때 인덱스도 함께 출력하려면 어떻게 해야할까? 이때는 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

위의 코드와 같이 enumerate(a) 를 하면 인덱스와 요소를 동시에 꺼낼 수 있다.

그런데 인덱스를 0부터 출력하는 것이 아니라 1부터 출력하고 싶을 때도 있을 것이다. 그렇다면

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

위 코드와 같이 간단하게 index + 1 을 해주면 된다. 하지만 좀 더 파이썬 다운 방법이 있다. 다음과 같이 enumeratestart 를 지정해주면 된다.

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

start 에 1을 지정하여 인덱스가 1부터 시작되도록 하였다. 이 코드는 enumerate(a, 1) 과 같이 간단하게 줄여서 사용할 수도 있다.

% for 반복문에서 인덱스로 요소를 출력하기

for 에서 인덱스를 지정하여 요소를 가져오려면 rangelen 을 사용하면 된다.

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

이렇게 하면 i 에는 요소가 들어가는 것이 아니라 0 부터 마지막 인덱스까지 들어가게 된다.

3-2 while 반복문 사용

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

변수 i 를 0으로 만들어주고 i < len(a) 까지 하여 변수 i 에는 4까지 들어가게 된다. 여기서 주의할 점은 < 대신에 <= 를 하면 i 에 5까지 들어가게 되고 print(a[5]) 가 실행되어 주어진 인덱스 범위를 초과하여 접근하기 때문에 오류가 발생한다.

a = [38, 21, 53, 62, 19]
i = 0
while i <= len(a):
	print(a[i])
	i += 1
38
21
53
62
19
Traceback (most recent call last):
  File "/Users/choewonjun/Documents/GitHub/C_TIL/python_TIL/14_list_tuple/main.py", line 129, in <module>
    print(a[i])
IndexError: list index out of range

즉, 인덱스는 0 부터 시작하고 마지막 인덱스는 리스트의 길이보다 1 작아야 하므로 < 를 사용해야 한다.

4. 가장 작은 수, 큰 수, 합계 구하기

가장 작은 수, 큰 수

먼저 가장 작은 수를 구해보자 어떻게 구해볼까? 앞서 반복문을 배웠으니까 반복문을 활용하여 요소들을 비교하고 더 작은 요소를 변수의 저장하고 그 변수와 다음 요소와의 크기를 비교하는 방식으로 코드를 만들어보면 될 것 같다.

a = [38, 21, 53, 62, 19]
smallest = a[0]
for i in a:
	if i < smallest:
		smallest = i
print(largest)
19

먼저 리스트의 첫 번째 요소를 변수에 할당하고 요소 하나씩 가져와 크기를 비교하는 것이다. 만약 현재 비교중인 요소가 더 작다면 그 요소를 smallest 라는 변수에 할당해주면 된다.

그렇다면 가장 큰 수를 구하려면 어떻게 해야할까? 그냥 간단하게 < 에서 > 로 바꿔주면 된다.

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

간단하다.

그런데 이러한 작업들은 반복문과 조건문을 사용해야해서 조금 번거롭다. 다른 방법은 없을까?

앞서 우리는 sort 라는 메서드에 대해서 배웠었다. 이 메서드를 사용하면 리스트를 오름차순으로 정렬하게 된다. 반대로 reverse=True 를 하면 내림차순으로 정렬된다.

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

이것보다 더 간단한 방법이 있는데 파이썬에서 제공하는 함수인 minmax 를 사용하는 방법이다.

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

요소 합계 구하기

이번에는 리스트의 모든 요소들의 합을 구해보자. 물론 반복문을 사용하는 방법이 있을 것이다.

a = [10, 10, 10, 10, 10]
x = 0
for i in a:
	x += i
print(x)
50

위와 같이 하는 방법이 있다. 이때 x 에는 반드시 0을 할당해야한다. 왜냐하면 값을 할당하지 않고 x += i 를 하게 되면 정의되지 않는 변수에 i 를 더하는 작업을 하게 되어 오류가 발생한다. 또한 0부터 시작해서 숫자를 더해야 제대로 된 합계가 구해질 것이다.

사실 이 방법도 좀 번거롭다. 그래서 파이썬에서는 합계를 구하는 함수 sum 을 제공한다.

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

여기서 설명한 max, min, sum 에는 리스트 뿐만 아니라 모든 반복 가능한 객체(iterable) 를 넣을 수 있다. 반복 가능한 객체로는 리스트, 튜플, 딕셔너리, 세트, range 등 여러가지가 있으며 자세한 내용은 뒤에서 알아보자

5. 리스트 표현식 (리스트 컴프리헨션)

파이썬의 리스트가 특이한 점은 리스트 안에 for 반복문과 if 조건문을 사용할 수 있다는 점이다. 이렇게 리스트 안에 식, for 반복문, if 조건문 등을 지정하여 리스트를 생성하는 것을 리스트 컴프리헨션(list comprehension) 이라고 한다.

리스트 컴프리헨션이라고 하니까 잘 이해가 안될 것이다. 책이나 인터넷에서도 리스트 내포, 리스트 내장, 리스트축약, 리스트 해석 등으로 쓴다. 컴프리헨션은 이해력, 능력, 시험 등의 뜻이 있지만 어떠한 것을 잡아서 담아둔다는 뜻이 있다. 즉, 식으로 지정하여 생성된 것을 리스트로 잡아두는 것이 컴프리헨션이다. 개념적으로 보면 리스트 표현식 이라고 할 수 있으니까 앞으로 리스트 표현식이라고 하겠다.

  • [식 for 변수 in 리스트]
  • list(식 for 변수 in 리스트)

리스트 표현식은 다음과 같이 리스트 안에 식이나 for 반복문을 지정한다. 문법이 다소 복잡해 보일 수 있으나 여러줄로 표현해야하는 코드를 간단하게 한 줄로 표현할 수 있고 익숙해지면 크게 어렵지 않다.

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

Untitled

[i for i in range(10)] 는 변수 i 를 그대로 사용하지만 다음과 같이 i 에 다른 값과 연산된 결과를 리스트에 저장할 수도 있다.

>>> a = [i * 2 for i in range(10)]
>>> a
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

% 대괄호와 list()

리스트 표현식은 [i for i in range(5)] 와 같이 대괄호를 이용해서 표현할 수도 있고 list(i for i in range(5) 와 같이 list 를 사용하는 방법으로도 표현할 수 있다. 이 둘 중에 성능은 대괄호를 사용하는 방식이더 좋다. 특히 list 방식은 C 언어 스타일이라서 대괄호를 사용하는 방식이 더 파이썬 다운 코드이다. 따라서 리스트 표현식은 대괄호를 사용하는 방식이 더 좋다. list 는 리스트 표현식을 만들 수 있다 정도로만 알아두면 된다.

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

이번에는 리스트 표현식에서 if 문도 사용해보자 if 문은 for 문 뒤에 지정한다.

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

위 리스트 표현식은 i 에 0부터 9까지 들어가는데 i % 2 == 0 을 만족하는 숫자, 즉 짝수들만 a 리스트에 저장이 된다.

Untitled

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

리스트 표현식에서는 for 반복문이나 if 조건문을 여러 번 사용해도 된다. 다음은 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]

여기에선 코드를 한 줄로 작성하였지만 가독성을 위해서 다음과 같이 여러 줄로 입력해도 된다. 이때 들여쓰기는 해도 되고 하지 않아도 된다 하지만 가독성을 위해 들여쓰기는 해주는 것이 좋다.

a = [i * j for i in range(2, 10)
					 for j in range(1, 10)]

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

Untitled

6. 리스트에서 map 사용하기

이번에는 리스트에 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])
print(a)
1 2 3 4

이렇게 반복문을 활용한 방법이 있다. 그런데 매번 반복문을 사용하기엔 번거롭다. 이때는 map 을 활용하면 편하다.

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

a = list(map(int, a)) 로 간단하게 한 줄로 변환이 되었다. mapint 와 리스트를 넣으면 모든 리스트의 요소들이 int 로 변환한다. 그다음에 list 를 통해서 다시 리스트로 만들어준다.

Untitled

사실 map 에는 리스트 뿐만 아니라 모든 반복 가능한 객체를 넣을 수 있다.(반복 가능한 객체). 이번에는 range 를 통해 숫자를 만든뒤에 map 을 이용하여 숫자들을 문자열로 바꿔보자

a = list(map(str, range(10)))
print(a)
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']

input 에서 map 활용

사실 앞에서 input 을 하면서 map 을 사용했던 것을 기억할 것이다.

>>> a = input().split()
10 20 (입력)
>>> a
['10', '20']

다음과 같이 iuput 을 통해서 숫자를 입력받아도 문자열로 저장이 되기 때문에 우리는 map 을 이용하여 int 형으로 바꿔주었다.

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

다시 10 20 을 입력하였을 때 맵 객체(map object)가 만들어지고 이 상태로는 안에 내용을 볼 수 없기 때문에 list 를 사용하여 리스트를 출력하였다.

이 리스트 [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               # 맵 객체는 변수 여러 개에 저장할 수 있음

내용이 조금 복잡하다. 이처럼 파이썬에서는 여러 객체와 함수를 조합하여 결과를 만들어낸다. 파이썬을 처음 접할 때는 이해하기 어려운 것이 당연하니까 이런 것이 있구나 하고 넘어가면 된다.

profile
벨로그보단 티스토리를 사용합니다! https://flight-developer-stroy.tistory.com/

0개의 댓글