7편. Python 컬렉션 정리 – Java List/Map/Set과의 대응 구조
📚 목차
1. ArrayList vs list - 순차형 컬렉션을 간결하게 다루기
2. HashMap vs dict - 키-값 구조의 차이와 유연성
3. HashSet vs set - 중복 없는 컬렉션과 집합 연산
4. 컬렉션 순회와 CRUD - Java보다 직관적인 문법
✔ 마무리 - 익숙한 개념, 새로운 문법에 적응하는 법
Python은 list, dict, set이라는 세 가지 기본 컬렉션 타입을 내장 형태로 제공합니다.
이들은 Java의 ArrayList, HashMap, HashSet과 유사한 역할을 하며, 문법은 훨씬 간결하고 사용법도 직관적입니다.
Java에 익숙한 개발자라면 Python 컬렉션을 단순히 새로운 문법으로 받아들이기보다, 익숙한 개념을 더 간단하게 표현하는 방식으로 이해하면 빠르게 적응할 수 있습니다.
이 글은 Java와 Python 컬렉션의 구조와 사용법을 1:1로 비교하면서, Python에 처음 입문하는 Java 개발자도 최소한의 학습 곡선으로 핵심을 익힐 수 있도록 구성되었습니다.
1. ArrayList vs list – 순차형 컬렉션을 간결하게 다루기
순서가 있고 중복을 허용하며, 인덱스를 통해 요소에 접근하는 컬렉션입니다.

✔️ Java: ArrayList 사용 예시
Java의 ArrayList는 java.util 패키지에 속하는 동적 배열(dynamic array) 구현체입니다.
크기가 자동으로 조절되며, 요소를 추가하거나 삭제할 수 있습니다.
제네릭(List<String>)을 사용하여 저장될 요소의 타입을 명시합니다
// Java 예시: ArrayList 사용법
import java.util.ArrayList;
import java.util.List;
List<String> names = new ArrayList<>(); // String 타입의 ArrayList 선언
names.add("Alice"); // 요소 추가
names.add("Bob");
names.add("Charlie");
System.out.println("두 번째 이름: " + names.get(1)); // 인덱스를 통한 요소 접근 (결과: Bob)
System.out.println("리스트 크기: " + names.size()); // 리스트의 크기
names.remove("Bob"); // "Bob" 요소 제거
System.out.println("Bob 제거 후: " + names); // 결과: [Alice, Charlie]
✔️ Python: list 사용 예시
Python의 list는 가장 기본적인 순차형 컬렉션입니다.
ArrayList와 마찬가지로 동적으로 크기가 조절되며, 다양한 타입의 데이터를 함께 저장할 수 있습니다(동적 타이핑).
대괄호([])를 사용하여 선언하거나 list() 생성자를 사용할 수 있습니다.
# Python 예시: list 사용법
names = ["Alice", "Bob", "Charlie"] # list 선언
print("두 번째 이름:", names[1]) # 인덱스를 통한 요소 접근 (결과: Bob)
names.append("David") # 요소 추가
print("David 추가 후:", names) # 결과: ['Alice', 'Bob', 'Charlie', 'David']
names.insert(1, "Anna") # 특정 인덱스에 요소 삽입
print("Anna 삽입 후:", names) # 결과: ['Alice', 'Anna', 'Bob', 'Charlie', 'David']
names.pop(2) # 인덱스를 통한 요소 제거 (Bob 제거)
print("Bob 제거 후:", names) # 결과: ['Alice', 'Anna', 'Charlie', 'David']
print("리스트 길이:", len(names)) # 리스트의 길이
✔️주요 비교 요약
| 항목 | Java(ArrayList) | Python(list) |
| 선언 방식 | new ArrayList<>() | 대괄호 [] 또는 list() |
| 타입 지정 | 제네릭 사용 (<T>) | 동적 타이핑 (단일 리스트에 여러 타입 가능) |
| 요소 추가 | .add(element) | .append(element), .insert(index, element) |
| 요소 삽입 | .add(index, element) | .insert(index, element) |
| 인덱스 접근 | .get(index) | [index] |
| 요소 삭제 | .remove(element), .remove(index) | .remove(element), .pop(index), del list[index] |
| 길이/크기 | .size() | len(list) |
| 반복 순회 | for-each, for 루프 | for in 루프 |
| 부분 추출 | .subList(from, to) | 슬라이싱 [start:end:step] |
Python list는 슬라이싱 기능, 음수 인덱스, 다양한 타입 혼합 등에서 더 높은 표현력을 제공합니다.

✔️ Python 실전 예시
# Python 실전 예시: list 활용
fruits = []
fruits.append("Apple")
fruits.append("Banana")
fruits.append("Cherry")
fruits.append("Banana") # 중복 허용
print("--- 모든 과일 순회 ---")
for fruit in fruits:
print(fruit)
print("\n--- 특정 인덱스 접근 ---")
print("첫 번째 과일:", fruits[0]) # 결과: Apple
print("마지막 과일:", fruits[-1]) # 결과: Banana (음수 인덱스 지원)
print("\n--- 특정 범위의 과일 (슬라이싱) ---")
print("두 번째부터 세 번째 과일:", fruits[1:3]) # 결과: ['Banana', 'Cherry']
print("\n--- 'Banana'가 리스트에 있는지 확인 ---")
if "Banana" in fruits:
print("Banana는 리스트에 있습니다.")
print("\n--- 'Banana' 제거 (첫 번째 발견된 요소) ---")
fruits.remove("Banana")
print("Banana 제거 후:", fruits) # 결과: ['Apple', 'Cherry', 'Banana']
print("\n--- 모든 요소 지우기 ---")
fruits.clear()
print("모든 과일 지운 후:", fruits) # 결과: []
2. HashMap vs dict – 키-값 구조의 차이와 유연성
키(key)와 값(value)의 쌍으로 데이터를 저장하는 컬렉션입니다. 키는 고유해야 하며, 이를 통해 값에 접근합니다.

✔️ Java: HashMap 사용 예시
Java의 HashMap은 java.util 패키지에 속하며, 키-값 쌍을 저장하는 컬렉션입니다.
해싱(hashing)을 이용하여 데이터를 저장하므로 키를 통해 매우 빠르게 값에 접근할 수 있습니다.
키는 중복될 수 없지만, 값은 중복될 수 있습니다.
// Java 예시: HashMap 사용법
import java.util.HashMap;
import java.util.Map;
Map<String, Integer> ages = new HashMap<>(); // String 키, Integer 값의 HashMap 선언
ages.put("Alice", 25); // 키-값 쌍 추가
ages.put("Bob", 30);
ages.put("Charlie", 28);
System.out.println("Bob의 나이: " + ages.get("Bob")); // 키를 통한 값 접근 (결과: 30)
System.out.println("HashMap 크기: " + ages.size()); // HashMap의 크기
// 키를 통해 값 수정
ages.put("Alice", 26);
System.out.println("Alice의 새로운 나이: " + ages.get("Alice")); // 결과: 26
// 키의 존재 여부 확인
if (ages.containsKey("Charlie")) {
System.out.println("Charlie가 HashMap에 있습니다.");
}
// 키-값 쌍 반복 순회
for (Map.Entry<String, Integer> entry : ages.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
✔️ Python: dict 사용 예시
Python의 dict (dictionary)는 HashMap과 동일하게 키-값 쌍으로 데이터를 저장합니다.
중괄호({})를 사용하여 선언하거나 dict() 생성자를 사용할 수 있습니다.
키는 해시 가능(hashable)한 불변(immutable) 객체여야 합니다(예: 문자열, 숫자, 튜플).
# Python 예시: dict 사용법
ages = {"Alice": 25, "Bob": 30, "Charlie": 28} # dict 선언
print("Bob의 나이:", ages["Bob"]) # 키를 통한 값 접근 (결과: 30)
ages["David"] = 35 # 새로운 키-값 쌍 추가
print("David 추가 후:", ages)
ages["Alice"] = 26 # 기존 키의 값 수정
print("Alice 나이 수정 후:", ages)
print("딕셔너리 길이:", len(ages)) # 딕셔너리의 길이
✔️ 주요 비교 요약
| 항목 | Java(HashMap) | Python(dict) |
| 선언 방식 | new HashMap<>() | 중괄호 {} 또는 dict() |
| 타입 지정 | <Key, Value> 제네릭 사용 | 동적 타이핑 (여러 타입의 키/값 가능) |
| 요소 추가 | .put(key, value) | dict[key] = value |
| 키로 접근 | .get(key) 또는 .getOrDefault(key, default) | dict[key], .get(key), .get(key, default_value) |
| 요소 삭제 | .remove(key) | del dict[key], .pop(key) |
| 키 존재 확인 | .containsKey(key) | key in dict |
| 순회 방식 | .entrySet(), .keySet(), .values() | for key in dict:, .keys(), .values(), .items() |
Python의 dict는 JSON과 매우 유사하며, 웹 개발이나 API 응답 처리 시 특히 강력한 표현력을 발휘합니다.
✔️ Python 실전 예시 (dict):
# Python 실전 예시: dict 활용
user = {"id": 1, "name": "Alice", "email": "alice@example.com"}
print("--- 값 읽기 ---")
print("사용자 이름:", user["name"]) # 결과: Alice
print("사용자 이메일 (get 메서드):", user.get("email")) # 결과: alice@example.com
print("존재하지 않는 키 (기본값 제공):", user.get("phone", "없음")) # 결과: 없음
print("\n--- 값 수정 ---")
user["email"] = "new_alice@example.com"
print("이메일 수정 후:", user["email"]) # 결과: new_alice@example.com
print("\n--- 새로운 키-값 추가 ---")
user["age"] = 30
print("age 추가 후:", user)
print("\n--- 키-값 쌍 전체 순회 ---")
for key, value in user.items(): # .items()는 (키, 값) 튜플을 반환
print(f"{key}: {value}")
print("\n--- 키만 순회 ---")
for key in user.keys(): # .keys()는 키만 반환 (생략 가능)
print(key)
print("\n--- 값만 순회 ---")
for value in user.values(): # .values()는 값만 반환
print(value)
print("\n--- 'id' 키 제거 ---")
del user["id"]
print("id 제거 후:", user)
print("\n--- 'email' 키 제거 후 값 반환 ---")
removed_email = user.pop("email")
print(f"제거된 이메일: {removed_email}, 남은 딕셔너리: {user}")
3. HashSet vs set – 중복 없는 컬렉션과 집합 연산
순서가 없고 중복을 허용하지 않는 컬렉션입니다. 주로 고유한 요소들의 집합을 다룰 때 사용됩니다.

✔️Java: HashSet 사용 예시
Java의 HashSet은 java.util 패키지에 속하며, 중복을 허용하지 않는 요소들의 집합을 저장합니다. 요소들의 삽입 순서가 유지되지 않습니다.
// Java 예시: HashSet 사용법
import java.util.HashSet;
import java.util.Set;
Set<String> colors = new HashSet<>(); // String 타입의 HashSet 선언
colors.add("Red"); // 요소 추가
colors.add("Green");
colors.add("Blue");
colors.add("Red"); // "Red"는 이미 존재하므로 무시됨 (중복 없음)
System.out.println("HashSet 내용: " + colors); // 결과: [Red, Green, Blue] (순서 보장 안됨)
// 요소 존재 여부 확인
if (colors.contains("Green")) {
System.out.println("Green은 집합에 있습니다.");
}
// 요소 제거
colors.remove("Blue");
System.out.println("Blue 제거 후: " + colors); // 결과: [Red, Green]
// 집합의 크기
System.out.println("HashSet 크기: " + colors.size());
✔️Python: set 사용 예시
Python의 set은 HashSet과 유사하게 중복을 허용하지 않는 요소들의 순서 없는 컬렉션입니다. 중괄호({})를 사용하거나 set() 생성자를 사용하여 선언합니다.
# Python 예시: set 사용법
colors = {"Red", "Green", "Blue"} # set 선언
colors.add("Red") # "Red"는 이미 존재하므로 추가되지 않음
print("set 내용:", colors) # 결과: {'Red', 'Green', 'Blue'} (순서 보장 안됨)
colors.add("Yellow") # 새로운 요소 추가
print("Yellow 추가 후:", colors)
# 요소 제거
colors.remove("Green")
print("Green 제거 후:", colors)
print("set 길이:", len(colors)) # set의 길이
✔️ 주요 비교 요약
| 항목 | Java(HashSet) | Python(set) |
| 선언 방식 | new HashSet<>() | 중괄호 {} 또는 set() |
| 중복 제거 기능 | 자동 중복 제거 | 자동 중복 제거 |
| 요소 추가 | .add(element) | .add(element) |
| 요소 삭제 | .remove(element) | .remove(element), .discard(element) |
| 요소 존재 확인 | .contains(element) | element in set |
| 집합 연산 | 별도 메서드 사용 (addAll(), retainAll(), removeAll()) | 합집합(` |
| 길이/크기 | .size() | len(set) |
Python의 set은 집합 연산이 연산자 형태로 제공되며, 수학적 집합 개념에 매우 직관적으로 대응합니다.
✔️ Python 실전 예시 (set)
Python의 set은 집합 연산을 위한 편리한 연산자(|, &, -, ^)를 제공합니다.
# Python 실전 예시: set 활용
a = {"apple", "banana", "cherry"}
b = {"banana", "cherry", "date", "elderberry"}
print("--- 집합 a:", a)
print("--- 집합 b:", b)
print("\n--- 합집합 (Union) ---")
print("a | b:", a | b) # 결과: {'cherry', 'apple', 'date', 'elderberry', 'banana'}
print("a.union(b):", a.union(b)) # 동일한 결과
print("\n--- 교집합 (Intersection) ---")
print("a & b:", a & b) # 결과: {'cherry', 'banana'}
print("a.intersection(b):", a.intersection(b)) # 동일한 결과
print("\n--- 차집합 (Difference) ---")
print("a - b:", a - b) # 결과: {'apple'} (a에만 있는 요소)
print("b - a:", b - a) # 결과: {'date', 'elderberry'} (b에만 있는 요소)
print("a.difference(b):", a.difference(b)) # 동일한 결과
print("\n--- 대칭 차집합 (Symmetric Difference) ---")
# 두 집합 중 어느 한쪽에만 있는 요소들 (공통 요소 제외)
print("a ^ b:", a ^ b) # 결과: {'apple', 'date', 'elderberry'}
print("a.symmetric_difference(b):", a.symmetric_difference(b)) # 동일한 결과
print("\n--- 부분집합 (Subset) 및 상위집합 (Superset) 확인 ---")
set_c = {"banana", "cherry"}
print(f"c ({set_c})는 a ({a})의 부분집합인가? {set_c.issubset(a)}") # 결과: True
print(f"a ({a})는 c ({set_c})의 상위집합인가? {a.issuperset(set_c)}") # 결과: True
print("\n--- 요소 추가 및 제거 ---")
my_set = {1, 2, 3}
my_set.add(4)
print("4 추가 후:", my_set) # 결과: {1, 2, 3, 4}
my_set.discard(2) # 요소가 없어도 에러 발생 안 함
print("2 제거 후 (discard):", my_set) # 결과: {1, 3, 4}
my_set.remove(1) # 요소가 없으면 KeyError 발생
print("1 제거 후 (remove):", my_set) # 결과: {3, 4}
# my_set.remove(99) # Uncommenting this line will cause a KeyError
4. 컬렉션의 순회와 CRUD – Java보다 직관적인 문법
Java에서는 컬렉션 타입에 따라 Iterator, for-each, 인덱스 기반 for 루프 등 다양한 반복 방식과 메서드를 사용합니다.
Python은 이보다 훨씬 간결하고 일관된 문법으로 CRUD(Create, Read, Update, Delete) 작업을 수행할 수 있습니다.
✔️Java vs Python 비교 요약
작업 Java 예시 (ArrayList 기준) Python 예시 (list 기준)
| 작업 | Java 예(ArrayList 기준) | Python 예(list 기준) |
| Create | list.add("X") | list.append("X") 또는 list.insert(index, "X") |
| Read | list.get(0) | list[0] |
| Update | list.set(0, "Y") | list[0] = "Y" |
| Delete | list.remove("X"), list.remove(index) | list.remove("X"), del list[0], list.pop(index) |
✔️ Python 컬렉션별 CRUD 실전 예시
# Python 실전 예시: 컬렉션별 CRUD
# --- list CRUD ---
print("--- list CRUD ---")
data_list = ["A", "B", "C", "D"]
print("초기 리스트:", data_list)
# Create (추가)
data_list.append("E") # 맨 뒤에 추가
print("append('E') 후:", data_list) # 결과: ['A', 'B', 'C', 'D', 'E']
data_list.insert(1, "F") # 인덱스 1에 'F' 삽입
print("insert(1, 'F') 후:", data_list) # 결과: ['A', 'F', 'B', 'C', 'D', 'E']
# Read (읽기)
print("인덱스 2의 요소:", data_list[2]) # 결과: B
print("슬라이싱 [1:4]:", data_list[1:4]) # 결과: ['F', 'B', 'C']
# Update (수정)
data_list[2] = "B_updated" # 인덱스 2의 값 수정
print("data_list[2] = 'B_updated' 후:", data_list) # 결과: ['A', 'F', 'B_updated', 'C', 'D', 'E']
# Delete (삭제)
data_list.remove("D") # 값 'D' 제거 (첫 번째 일치하는 값)
print("remove('D') 후:", data_list) # 결과: ['A', 'F', 'B_updated', 'C', 'E']
deleted_item = data_list.pop(0) # 인덱스 0의 요소 제거 및 반환
print(f"pop(0) (제거된 요소: {deleted_item}) 후:", data_list) # 결과: ['F', 'B_updated', 'C', 'E']
del data_list[0] # 인덱스 0의 요소 제거
print("del data_list[0] 후:", data_list) # 결과: ['B_updated', 'C', 'E']
data_list.clear() # 모든 요소 제거
print("clear() 후:", data_list) # 결과: []
print("\n--- dict CRUD ---")
# --- dict CRUD ---
data_dict = {"name": "Alice", "age": 25, "city": "Seoul"}
print("초기 딕셔너리:", data_dict)
# Create (추가) / Update (수정) - 동일한 문법 사용
data_dict["country"] = "Korea" # 새로운 키-값 추가
print("country 추가 후:", data_dict)
data_dict["age"] = 26 # 기존 키의 값 수정
print("age 수정 후:", data_dict)
# Read (읽기)
print("이름:", data_dict["name"])
print("도시 (get):", data_dict.get("city"))
print("폰 번호 (기본값):", data_dict.get("phone", "N/A"))
# Delete (삭제)
del data_dict["city"] # 키 'city' 제거
print("del data_dict['city'] 후:", data_dict)
removed_age = data_dict.pop("age") # 키 'age' 제거 및 값 반환
print(f"pop('age') (제거된 값: {removed_age}) 후:", data_dict)
data_dict.clear() # 모든 요소 제거
print("clear() 후:", data_dict)
print("\n--- set CRUD ---")
# --- set CRUD ---
data_set = {"apple", "banana", "cherry"}
print("초기 집합:", data_set)
# Create (추가)
data_set.add("date") # 요소 추가
print("add('date') 후:", data_set)
# Read (존재 여부 확인)
print("'banana'가 집합에 있는가?", "banana" in data_set)
print("'grape'가 집합에 있는가?", "grape" in data_set)
# Update (집합은 요소 자체를 수정하는 개념이 없음; 추가/삭제를 통해 변경)
# 예를 들어, 'banana'를 'kiwi'로 바꾸려면 'banana'를 제거하고 'kiwi'를 추가해야 함
data_set.remove("banana")
data_set.add("kiwi")
print("banana를 kiwi로 변경 후:", data_set)
# Delete (삭제)
data_set.discard("date") # 'date' 제거 (없어도 에러 없음)
print("discard('date') 후:", data_set)
data_set.remove("cherry") # 'cherry' 제거 (없으면 에러 발생)
print("remove('cherry') 후:", data_set)
data_set.clear() # 모든 요소 제거
print("clear() 후:", data_set)
Python의 컬렉션은 CRUD 작업을 위한 일관된 문법과 직관적인 표현이 특징입니다. 복잡한 반복문이나 명시적 타입 선언 없이도 자유롭게 조작할 수 있습니다.
✔ 마무리 - 익숙한 개념, 새로운 문법에 적응하는 법
Java 개발자에게 Python의 컬렉션은 전혀 생소한 구조가 아닙니다.
오히려 Python은 Java의 익숙한 개념(ArrayList, HashMap, HashSet)을 훨씬 간결하게 표현한 언어입니다.
Python의 list, dict, set은 선언이 단순하고 동적으로 타입을 처리하며,반복, 조건, 추가/삭제 등 대부분의 작업을 명확한 문법으로 빠르게 처리할 수 있습니다.
📌요약
🔸 list는 ArrayList처럼 순서를 가지며, 다양한 타입을 동시에 담을 수 있는 유연한 컬렉션입니다.
🔸 dict는 HashMap보다 직관적이며, JSON과도 유사해 웹 개발에서 특히 유용합니다.
🔸 set은 중복 없는 집합을 간결하게 다루며, 수학적 집합 연산도 연산자만으로 처리할 수 있습니다.
🔸 CRUD 작업도 Java보다 훨씬 단순하고, 반복문 구조도 통일되어 읽고 쓰기 쉬운 코드 작성이 가능합니다.
Python은 복잡한 제약보다 표현의 자유와 개발 속도를 우선합니다.
하지만 자유로운 만큼, 코드의 명확성을 유지하려면 일관된 컬렉션 활용 방식과 코드 스타일을 갖추는 것이 중요합니다.
Java 개발자라면, 익숙한 구조를 기반으로 Python 문법에 빠르게 적응할 수 있습니다.
※ 게시된 글 및 이미지 중 일부는 AI 도구의 도움을 받아 생성되거나 다듬어졌습니다.
'3.SW개발 > Python' 카테고리의 다른 글
| [Java관점]9편. Python 모듈과 import – Java와 다른 가져오기 구조 이해하기 (0) | 2025.11.13 |
|---|---|
| [Java관점]8편. Python 멀티스레딩 vs GIL – Java와 Python 병렬 처리 방식 비교 (0) | 2025.11.13 |
| [Java관점]6편. Python 예외 처리 문법 – Java와 Python의 처리 구조 비교 (0) | 2025.11.12 |
| [Java관점]5편. Python 클래스와 객체지향 – Java보다 유연한 설계 방식 이해하기 (1) | 2025.11.12 |
| [Java관점]4편. Python 함수와 메서드 – 호출 방식과 선언 구조 비교 (0) | 2025.11.11 |