알고리즘 Cheat Sheet 시리즈는 코딩 테스트를 풀다가 "이거 자바에선 뭐였지?", "파이썬은 어떻게 했더라?" 싶을 때 바로 펼쳐 보려고 만든 개인 참고용 정리입니다.
Java와 Python을 나란히 놓고, 문법 차이 때문에 실수하기 쉬운 부분만 짧게 정리합니다.

이번 주제는 배열 · 리스트 · 문자열 기초입니다.
길이 구하기, 순회, 복사, 정렬처럼 매 문제마다 쓰는 기본기인데, 자바는 대상마다 문법이 다르고 파이썬은 거의 하나로 통일되어 있어서 자주 헷갈립니다.
| 대상 | 자바 | 파이썬 |
|---|---|---|
| 배열 | arr.length | len(arr) |
| 문자열 | s.length() | len(s) |
StringBuilder | sb.length() | - |
| 리스트 | list.size() | len(lst) |
| 맵 · 셋 | map.size(), set.size() | len(d), len(s) |
| 2차원 배열 행 · 열 | grid.length, grid[0].length | len(grid), len(grid[0]) |
자바는 배열은 필드(
length), 문자열은 메서드(length()), 컬렉션은size()로 외우자!
파이썬은 무엇이든len()하나면 된다.
int[] arr = {1, 2, 3};
String s = "abc";
List<Integer> list = List.of(1, 2, 3);
arr.length; // 3 (괄호 없음)
s.length(); // 3 (괄호 있음)
list.size(); // 3
len([1, 2, 3]) # 3
len("abc") # 3
| 상황 | 자바 | 파이썬 |
|---|---|---|
| 크기 n, 0으로 초기화 | int[] arr = new int[n]; | arr = [0] * n |
| 값으로 초기화 | int[] arr = {1, 2, 3}; | arr = [1, 2, 3] |
| 특정 값으로 채우기 | Arrays.fill(arr, -1); | arr = [-1] * n |
| 가변 리스트 | List<Integer> list = new ArrayList<>(); | lst = [] |
| 2차원 n × m | int[][] grid = new int[n][m]; | grid = [[0] * m for _ in range(n)] |
파이썬 2차원 리스트를 [[0] * m] * n으로 만들면 안 된다.
모든 행이 같은 리스트를 가리켜서 한 칸을 바꾸면 모든 행이 같이 바뀐다.
grid = [[0] * 3] * 2
grid[0][0] = 1
print(grid) # [[1, 0, 0], [1, 0, 0]] ← 둘 다 바뀜
자바 Arrays.asList()와 List.of()는 크기를 바꿀 수 없다. add하면 예외가 난다. 추가하려면 new ArrayList<>(Arrays.asList(...))로 감싼다.
자바 int[]는 Arrays.asList()로 리스트가 되지 않는다. List<int[]>가 되어 버린다. 박싱이 필요하다.
List<Integer> list = Arrays.stream(arr).boxed().collect(Collectors.toList()); // int[] → List
int[] back = list.stream().mapToInt(Integer::intValue).toArray(); // List → int[]
| 상황 | 자바 | 파이썬 |
|---|---|---|
| 값만 | for (int x : arr) | for x in arr: |
| 인덱스만 | for (int i = 0; i < arr.length; i++) | for i in range(len(arr)): |
| 인덱스 + 값 | 인덱스로 순회 후 arr[i] | for i, x in enumerate(arr): |
| 인덱스를 1부터 | i + 1로 계산 | enumerate(arr, start=1) |
| 거꾸로 | for (int i = n - 1; i >= 0; i--) | for i in range(n - 1, -1, -1): / reversed(arr) |
| 두 배열 동시에 | 인덱스로 순회 | for a, b in zip(x, y): |
| 문자열 한 글자씩 | for (char c : s.toCharArray()) | for c in s: |
파이썬에서 인덱스와 값이 둘 다 필요할 때 쓰는 함수다. 자바에는 없으니 인덱스 for문을 쓴다.
fruits = ["apple", "banana", "cherry"]
for i, fruit in enumerate(fruits):
print(i, fruit) # 0 apple / 1 banana / 2 cherry
for i, fruit in enumerate(fruits, start=1):
print(i, fruit) # 1 apple / 2 banana / 3 cherry
String[] fruits = {"apple", "banana", "cherry"};
for (int i = 0; i < fruits.length; i++) {
System.out.println(i + " " + fruits[i]);
}
파이썬에서
for i in range(len(arr)):안에서arr[i]를 쓰고 있다면enumerate로 바꾸는 게 더 파이썬답다.
| 기능 | 자바 | 파이썬 |
|---|---|---|
| i번째 문자 | s.charAt(i) | s[i] |
| 마지막 문자 | s.charAt(s.length() - 1) | s[-1] |
부분 문자열 [a, b) | s.substring(a, b) | s[a:b] |
| 뒤집기 | new StringBuilder(s).reverse().toString() | s[::-1] |
| 공백으로 나누기 | s.split(" ") | s.split() |
| 합치기 | String.join(",", list) | ",".join(lst) |
| 문자 배열로 | s.toCharArray() | list(s) |
| 포함 여부 | s.contains("ab") | "ab" in s |
s.charAt(0) = 'x', s[0] = 'x' 모두 불가능하다. 문자 배열(리스트)로 바꿔서 수정한 뒤 다시 합친다. String s = "hello";
char[] cs = s.toCharArray(); // ['h', 'e', 'l', 'l', 'o']
cs[0] = 'j'; // 배열은 수정 가능
s = new String(cs); // "jello"
// StringBuilder도 가능
StringBuilder sb = new StringBuilder(s);
sb.setCharAt(0, 'y');
s = sb.toString(); // "yello"
s = "hello"
chars = list(s) # ['h', 'e', 'l', 'l', 'o']
chars[0] = "j" # 리스트는 수정 가능
s = "".join(chars) # "jello"
# 한 글자만 바꿀 거면 슬라이싱으로 새로 만들어도 된다
s = "y" + s[1:] # "yello"
반복문에서 문자열을 +로 이어 붙이지 말자. 매번 새 문자열이 만들어져서 느리다.
StringBuilder sb = new StringBuilder();
for (int x : arr) sb.append(x).append(" ");
String result = sb.toString();
result = " ".join(map(str, arr))
split 동작이 다르다. 파이썬 split()(인자 없음)은 연속된 공백도 하나로 보고 앞뒤 공백을 무시한다. 자바 split(" ")는 공백 하나 기준이라 빈 문자열이 섞일 수 있다. 자바에서 연속 공백을 처리하려면 s.trim().split("\\s+")를 쓴다.
| 상황 | 자바 | 파이썬 |
|---|---|---|
| 같은 객체 가리키기 (복사 아님) | int[] b = a; | b = a |
| 1차원 복사 | a.clone() / Arrays.copyOf(a, a.length) | a[:] / a.copy() / list(a) |
| 리스트 복사 | new ArrayList<>(list) | lst.copy() |
| 2차원 깊은 복사 | 행마다 clone() | [row[:] for row in a] / copy.deepcopy(a) |
int[][] copy = new int[n][];
for (int i = 0; i < n; i++) copy[i] = grid[i].clone();
b = a는 두 언어 모두 복사가 아니라 같은 배열을 가리키는 것이다.b를 바꾸면a도 바뀐다.
2차원 배열에clone()/a[:]만 쓰면 행은 여전히 공유된다(얕은 복사).
| 상황 | 자바 | 파이썬 |
|---|---|---|
| 원본 정렬 (배열) | Arrays.sort(arr) | - |
| 원본 정렬 (리스트) | Collections.sort(list) / list.sort(null) | lst.sort() |
| 정렬된 복사본 | int[] c = arr.clone(); Arrays.sort(c); | sorted(lst) |
| 리스트 정렬된 복사본 | list.stream().sorted().collect(Collectors.toList()) | sorted(lst) |
| 문자열 정렬 | char[] cs = s.toCharArray(); Arrays.sort(cs); new String(cs) | "".join(sorted(s)) |
sort() vs sorted()nums = [3, 1, 2]
a = sorted(nums) # a = [1, 2, 3], nums = [3, 1, 2] ← 원본 유지
nums.sort() # nums = [1, 2, 3] ← 원본 변경
lst.sort(): 리스트 원본을 정렬하고 None을 반환한다. 리스트에만 있는 메서드다.sorted(x): 원본은 그대로 두고 정렬된 새 리스트를 반환한다. 문자열, 튜플, 딕셔너리 등 순회 가능한 모든 것에 쓸 수 있다.nums = nums.sort() # (X) nums가 None이 된다
nums = sorted(nums) # (O)
sorted("dcba") # ['a', 'b', 'c', 'd']
sorted({"b": 1, "a": 2}) # ['a', 'b'] (딕셔너리는 키만)
자바의 Arrays.sort(), Collections.sort()는 항상 원본을 바꾼다. 원본을 남겨야 하면 먼저 복사하고 정렬한다.
length, 문자열 length(), 컬렉션 size(). 파이썬은 전부 len()[[0] * m for _ in range(n)]. [[0] * m] * n은 행이 공유된다.enumerate. 자바는 인덱스 for문b = a는 복사가 아니다. 1차원은 clone() / a[:], 2차원은 행마다 복사sort()는 원본 변경 + None 반환, sorted()는 새 리스트 반환. 자바 정렬은 항상 원본 변경StringBuilder / join