파이썬에서 map은 리스트의 요소를 지정된 함수로 처리해주는 함수다
map은 원본 리스트를 변경하지 않고 새 리스트를 생성한다.
기초적인 부분부터 시작하기 위해 예를 들어보자.
ex) 실수가 저장된 리스트가 있을 때 이 리스트의 모든 요소를 정수로 변환하려면 어떻게 해야할까? 먼저 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로 변환하여 다시 저장하였다.
매번 for 반복문으로 반복하면서 요소를 변환하려니 조금 번거로운데, 이때는 map 을 사용하면 편리하다.
>>> a = [1.2, 2.5, 3.7, 4.6]
>>> a=list(map(int,a))
>>> a
[1,2,3,4]
사실 map에는 리스트 뿐 만 아니라 반복 가능한 객체를 넣을 수 있다.
반복 가능한 객체는 (https://dojang.io/mod/page/view.php?id=2405) 에 있으며 나중에 정리 할 예정이다.
이게 map의 기본 정의 및 사용법이고, 이제 input을 받을 때 map을 활용하는 법을 알아보자.
지금까지 input().split()로 값을 여러개 입력받고 정수, 실수로 변환할 때도 map을 사용했었다.
사실, input().split()의 결과가 문자열 리스트라서 map을 사용하 수 있었따.
다음과 같이 input.split()을 사용한 뒤에 변수 한 개에 저장해보면 리스트인지 확인할 수 있다.
>>> 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]
다시 10,20 을 입력하면 맵 객체(map object)가 만들어진다.
이 상태로는 안에 들어있는 값을 볼 수 없으므로, list를 사용해서 리스트로 출력했다.
사실 map이 반환하는 맵 객체는 반복자(iterator)라서 변수 여러 개에 저장하는 언패킹(unpacking)이 가능하다.
그래서 a,b=map(int,input().split()) 처럼 list를 생략한 것이다.
이를 풀어서 쓰면 다음과 같은 코드가 된다.
x = input().split() # input().split()의 결과는 문자열 리스트
m = map(int, x) # 리스트의 요소를 int로 변환, 결과는 맵 객체
a, b = m # 맵 객체는 변수 여러 개에 저장할 수 있음
이제 입력받는 법은 알았다.
그럼 2차원 배열 입력을 받아야 하는데 어떻게 해야하나.
먼저 알기 전에 리스트 관련 함수들을 복습해보자
a=[1,2,3]
a.append("A")
print(a)
a.append((3,4))
print(a)
결과는
[1,2,3,'A']
[1,2,3,'A',(3,4)]
a=[1,2,3]
a.append(["a","b"])
print(a)
a.extned(["a","b"])
print(a)
a.extned((3,4))
print(a)
결과는,
[1,2,3,['a','b']]
[1,2,3,['a','b'],'a','b']
[1,2,3,['a','b'],'a','b',3,4]
extend()도 append()와 동일하게 리스트에 값을 추가해주는 메소드이다.
차이점이라면 리스트나 튜플 자체로 값이 되는게 아니라는 것이다.
리스트나 튜플을 풀어서 값을 넣는다.
+연산자 처럼 리스트를 합친다고 보면 된다.
a=[6,4,1,2,3,5.1]
print(a)
b=[0 for i in range(3)]
print(b)
결과는
[6,4,1,2,3,5.1]
[0, 0, 0]
보통 파이썬에서는 배열의 초기값을 주고 위와 같은 방식을 많이 사용한다.
2차원 배열에서도 위의 방법을 이용해서 동일하게 선언할 수 있다.
c=[[0 for i in range(3)] for j in range(5)]
print(c)
결과는
[[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]]
이를 바탕으로 백준 1932번을 설명할 겸 파이썬으로 풀어보도록 하겠다.
동적계획법을 사용해서 풀어야 하는 문제고, 간단하게 풀 수 있는 문제다.
점화식은 아래와 같다.
DP[i][j] = max(arr[i][j]+DP[i-1][j-1], arr[i][j]+DP[i-1][j])
c++ 코드는 아래와 같다.
#include <iostream>
using namespace std;
#define MAX 500
#include <algorithm>
int map[MAX+1][MAX+1];
int N;
int dp[MAX + 1][MAX + 1];
int main() {
cin >> N;
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= i; j++) {
scanf("%d", &map[i][j]);
}
}
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= i; j++) {
dp[i][j] = max(map[i][j] + dp[i - 1][j - 1], map[i][j] + dp[i - 1][j]);
}
}
int max = -1;
for (int i = 1; i <= N; i++) {
if (dp[N][i] > max) {
max = dp[N][i];
}
}
printf("%d", max);
return 0;
}
이제 이를 파이썬 코드로 변환해보자.
n=int(input())
t=[]
dp=[[0 for col in range(n)] for row in range(n)]
for i in range(n):
t.append(list(map(int,input().split())))
dp[0][0]=t[0][0]
for i in range(1,n):
for j in range(0, i+1):
if(j == 0):
dp[i][j] = t[i][j]+dp[i-1][j]
elif(j==i):
dp[i][j]=t[i][j]+dp[i-1][j-1]
else:
dp[i][j]=max(t[i][j] + dp[i - 1][j - 1], t[i][j] + dp[i - 1][j])
max=-1
for i in range(0,n):
if(dp[n-1][i]>max):
max=dp[n-1][i]
print(max)