파이썬 (1)

최준병·5일 전

파이썬

목록 보기
1/2

목차

  1. pass
  2. 자료구조
  3. == vs is
  4. 삼항연산자 대체
  5. 슬라이싱
  6. List Comprehension
  7. 딕셔너리 (Dictionary)
  8. f-string
  9. enumerate
  10. zip
  11. for-else

pass

블록 안에 아무것도 하지 않겠다 는 의미입니다.

Python은 Java와 달리 빈 블록 {} 을 허용하지 않습니다.
Python은 들여쓰기로 블록을 구분하기 때문에, 블록 안에 반드시 뭔가 있어야 합니다.

// Java - 빈 블록 허용
class MyClass {}
void myFunction() {}
# Python - 빈 블록 불가 → SyntaxError 발생
class MyClass:
    # 아무것도 없으면 에러!

# pass 로 해결
class MyClass:
    pass

def my_function():
    pass

if True:
    pass

나중에 구현할 예정인 코드 자리를 잡아둘 때 자주 사용합니다.

# 인터페이스처럼 구조만 잡아두기
class Animal:
    def speak(self):
        pass   # 나중에 구현 예정

    def move(self):
        pass   # 나중에 구현 예정

자료구조

리스트 (List)

Java의 ArrayList와 유사한 mutable(가변) 자료형입니다.
[] 로 표기하며, 서로 다른 타입의 요소도 함께 담을 수 있습니다.

a = [1, 2, 3]
a.append(4)        # [1, 2, 3, 4] - 요소 추가
a + [5, 6]         # [1, 2, 3, 4, 5, 6] - 리스트 합치기
a * 2              # [1, 2, 3, 4, 1, 2, 3, 4] - 반복

Java였다면 리스트 합치기에 addAll(), 반복은 루프를 직접 돌려야 했지만
Python은 +, * 연산자로 직관적으로 표현할 수 있습니다.

참조 타입 주의

리스트는 참조 타입이므로 단순 대입은 복사가 아닙니다.
Java의 객체 참조와 동일하게 동작합니다.

a = [1, 2, 3]
b = a           # b는 a와 동일한 리스트를 가리킴
b.append(4)
print(a)        # [1, 2, 3, 4] - a도 같이 변경됨!

# 진짜 복사를 원한다면
b = a.copy()    # shallow copy
b = a[:]        # 슬라이싱으로 복사 (Python스러운 방식)
b = list(a)     # list() 생성자 활용

튜플 (Tuple)

() 로 표기하며, immutable(불변) 자료형입니다.
한 번 생성하면 요소를 추가, 수정, 삭제할 수 없습니다.

a = (1, 2, 3)
a[0] = 99   # TypeError: 'tuple' object does not support item assignment

Java의 final List는 참조만 못 바꾸는 것이지만,
Python의 tuple은 내부 요소 자체를 아예 변경할 수 없습니다.

언제 튜플을 쓸까요?
변경되면 안 되는 데이터(좌표, 설정값 등)를 담을 때, 또는 함수에서 여러 값을 반환할 때 자연스럽게 사용됩니다.

point = (10, 20)           # 좌표처럼 변하면 안 되는 값
return min(a), max(a)      # 함수의 다중 반환값 (내부적으로 tuple)
ListTuple
문법[1, 2, 3](1, 2, 3)
수정✅ 가능❌ 불가능
Java 유사 개념ArrayList불변 객체

== vs is

Python의 ==is 는 전혀 다른 비교를 합니다.

PythonJava설명
==.equals() 비교
is==객체 동일성 비교 (같은 객체인가?)
a = [1, 2, 3]
b = [1, 2, 3]

print(a == b)   # True  - 값이 같음
print(a is b)   # False - 서로 다른 객체

None 비교는 is 를 권장

None 은 전역에 딱 하나만 존재하는 객체이기 때문에,
값 비교보다 객체 동일성 비교가 더 정확하고 빠릅니다.

a = None

if a is None:      # ✅ 권장
    pass
if a == None:      # 동작하지만 비권장
    pass

주의 - 정수 캐싱

Python은 -5 ~ 256 사이의 정수를 미리 캐싱해두기 때문에,
해당 범위 안의 숫자는 is 비교가 True 로 나옵니다.

a = 1
b = 1
print(a is b)     # True  - 캐싱 범위 내

a = 1000
b = 1000
print(a is b)     # False - 캐싱 범위 밖, 다른 객체

Java의 Integer 캐싱(-128 ~ 127)과 동일한 개념입니다.
따라서 숫자, 문자열에는 is 를 쓰지 않는 것이 원칙이고,
isNone, True, False 비교에만 쓰는 것이 관례입니다.


삼항연산자 대체

Java의 삼항연산자 ? : 를 Python에서는 아래와 같이 표현합니다.

# 기본 문법
참일때의_값 if 조건식 else 거짓일때의_값
// Java
String result = x > 5 ? "크다" : "작다";
# Python
result = "크다" if x > 5 else "작다"

Java와 순서가 반대라는 점을 주의하세요.
Java는 조건 ? 참 : 거짓 이지만, Python은 참 if 조건 else 거짓 입니다.

f-string 안에서도 사용할 수 있습니다.

age = 20
print(f"{'성인' if age >= 18 else '미성년자'}")  # "성인"

슬라이싱

순서가 있는 자료형(list, tuple, string)의 일부를 잘라내는 기법입니다.
Java의 subList(), substring() 을 훨씬 간결하게 표현할 수 있습니다.

기본 문법

[start:end:step]
  • start: 시작 인덱스 (포함, 기본값 0)
  • end: 끝 인덱스 (미포함, 기본값 len(a))
  • step: 간격 (기본값 1, 생략 가능)

end미포함이라는 점을 꼭 기억하세요.
a[1:4] 는 index 1, 2, 3 까지이고 4는 포함되지 않습니다.

생략 예시

a = [0, 1, 2, 3, 4]

a[1:4]    # [1, 2, 3]       - index 1~3 (4 미포함)
a[:3]     # [0, 1, 2]       - start 생략 → 0부터
a[2:]     # [2, 3, 4]       - end 생략 → 끝까지
a[:]      # [0, 1, 2, 3, 4] - 전체 복사
a[::2]    # [0, 2, 4]       - 하나씩 건너뜀 (step=2)
a[::-1]   # [4, 3, 2, 1, 0] - 역순 (step=-1)

step이 음수일 때

step이 음수이면 역방향으로 순회하기 때문에 기본값이 바뀝니다.

step > 0step < 0
start 기본값0 (처음부터)len(a) - 1 (끝부터)
end 기본값len(a) (끝까지)처음 요소까지 포함
a = [0, 1, 2, 3, 4]
a[::-1]     # [4, 3, 2, 1, 0] - 끝에서 처음까지 역순
a[3::-1]    # [3, 2, 1, 0]    - index 3부터 역순

슬라이싱 가능한 자료형

순서가 있는(sequential) 자료형이면 모두 슬라이싱이 가능합니다.

[1, 2, 3][1:]    # 리스트 ✅ → [2, 3]
(1, 2, 3)[1:]    # 튜플 ✅  → (2, 3)
"hello"[1:3]     # 문자열 ✅ → "el"

# Java와 비교
"hello".substring(1, 3)  // Java  → "el"
"hello"[1:3]             # Python → "el"

List Comprehension

리스트를 간결하게 생성하는 Python의 핵심 문법입니다.
Java의 Stream API와 개념이 유사하지만, 훨씬 짧게 표현할 수 있습니다.

기본 문법

[표현식 for 변수 in 반복가능객체 if 조건]

읽는 순서대로 해석하면 이렇습니다.

"반복가능객체에서 변수를 하나씩 꺼내서, 조건을 만족하는 것만, 표현식으로 변환해 리스트로 만든다"

if 조건 은 생략 가능합니다.

예시

numbers = [1, 2, 3, 4, 5]

# 조건 없이 - 모든 요소에 *2
[x * 2 for x in numbers]
# → [2, 4, 6, 8, 10]

# 조건 있이 - 짝수만 추출 후 *2
[x * 2 for x in numbers if x % 2 == 0]
# → [4, 8]

Java Stream API와 비교

// Java
numbers.stream()
    .filter(x -> x % 2 == 0)
    .map(x -> x * 2)
    .collect(Collectors.toList());
# Python - 한 줄로 끝
[x * 2 for x in numbers if x % 2 == 0]

중첩 List Comprehension

2차원 리스트를 1차원으로 펼칠 때도 사용할 수 있습니다.

matrix = [[1, 2, 3], [4, 5, 6]]

# "matrix의 각 row에서 x를 꺼내 펼친다"
[x for row in matrix for x in row]
# → [1, 2, 3, 4, 5, 6]

딕셔너리

Java의 HashMap에 해당하는 자료형입니다.
{key: value} 형태로 표기하며, key-value 쌍으로 데이터를 저장합니다.

기본 사용법

person = {
    "name": "Alice",
    "age": 30
}

# 요소 추가 / 수정
person["email"] = "alice@example.com"

# 요소 삭제
del person["age"]

요소 접근

딕셔너리에서 값을 꺼내는 방법은 두 가지입니다.

person["name"]              # "Alice"
person["email"]             # 키가 없으면 KeyError 발생 💥

person.get("email")         # 키가 없으면 None 반환 ✅
person.get("email", "없음") # 키가 없으면 기본값 반환 ✅

[] 접근 vs .get() 접근
키가 반드시 존재한다고 확신할 때 → []
키가 없을 수도 있을 때 → .get() (안전)

Python의 None은 Java의 null에 해당합니다.

Java HashMapPython dict
생성new HashMap<>(){}
값 접근map.get("key")dict["key"] 또는 dict.get("key")
키 없을 때null 반환dict["key"] → KeyError 발생
기본값 지정getOrDefault("key", "기본값")dict.get("key", "기본값")

f-string

Python 3.6부터 도입된 문자열 포맷팅 방법으로,
Java의 String.format() 보다 훨씬 직관적입니다.

문자열 앞에 f 를 붙이고, {} 안에 변수나 표현식을 넣으면 됩니다.

name = "Alice"
age = 30

# Java
String.format("이름: %s, 나이: %d", name, age)  // "이름: Alice, 나이: 30"

# Python f-string
f"이름: {name}, 나이: {age}"                     # "이름: Alice, 나이: 30"

{} 안에 표현식도 사용 가능

단순 변수 삽입뿐 아니라, 연산이나 메서드 호출도 바로 넣을 수 있습니다.

f"{2 + 3}"                                    # "5"
f"{name.upper()}"                             # "ALICE"
f"{'짝수' if age % 2 == 0 else '홀수'}"       # "짝수"
f"원주율: {3.14159:.2f}"                      # "원주율: 3.14" - 소수점 2자리

enumerate

리스트를 순회할 때 인덱스와 요소를 함께 가져올 수 있게 해줍니다.

fruits = ["apple", "banana", "kiwi"]

# Java
<for (int i = 0; i < fruits.size(); i++) {
    System.out.println(i + " " + fruits.get(i));
}

# Python - enumerate 없이
for i in range(len(fruits)):
    print(i, fruits[i])

# Python - enumerate 사용 ✅
for i, fruit in enumerate(fruits):
    print(i, fruit)
# 0 apple
# 1 banana
# 2 kiwi

동작 원리

enumerate 는 내부적으로 (index, 요소) 형태의 tuple 을 반환하는 iterator입니다.
for i, fruit in 은 이 tuple을 Unpacking 하는 것입니다.

enumerate(fruits)
# → (0, "apple"), (1, "banana"), (2, "kiwi") 를 하나씩 반환하는 iterator

# 즉, 아래와 동일
for item in enumerate(fruits):
    i, fruit = item   # Unpacking
    print(i, fruit)

시작 인덱스 지정

기본값은 0이지만, 시작 인덱스를 변경할 수 있습니다.

for i, fruit in enumerate(fruits, start=1):
    print(i, fruit)
# 1 apple
# 2 banana
# 3 kiwi

zip

여러 iterable을 같은 인덱스끼리 묶어서 tuple로 반환합니다.
두 리스트를 동시에 순회할 때 유용합니다.

fruits = ["apple", "banana", "kiwi"]
prices = [1000, 2000, 3000]

# Java - 인덱스로 직접 접근
for (int i = 0; i < fruits.size(); i++) {
    System.out.println(fruits.get(i) + " " + prices.get(i));
}

# Python - zip 사용 ✅
for fruit, price in zip(fruits, prices):
    print(fruit, price)
# apple 1000
# banana 2000
# kiwi 3000

동작 원리

zip 은 내부적으로 같은 인덱스의 요소를 tuple로 묶은 iterator입니다.

zip(fruits, prices)
# → ("apple", 1000), ("banana", 2000), ("kiwi", 3000) 을 하나씩 반환

# for fruit, price in 은 tuple을 Unpacking 하는 것

길이가 다를 때

리스트 길이가 다르면 짧은 쪽에 맞춰서 끊깁니다.

a = [1, 2, 3, 4, 5]
b = [10, 20, 30]

for x, y in zip(a, b):
    print(x, y)
# 1 10
# 2 20
# 3 30   ← b가 끝나면 중단

enumerate + zip 함께 사용

for i, (fruit, price) in enumerate(zip(fruits, prices)):
    print(f"{i}번: {fruit} - {price}원")
# 0번: apple - 1000원
# 1번: banana - 2000원
# 2번: kiwi - 3000원

for-else

반복문이 break 없이 정상적으로 끝났을 때 else 블록이 실행됩니다.
break 로 탈출하면 else 는 실행되지 않습니다.

numbers = [1, 2, 3, 4, 5]

# break 없이 끝난 경우 → else 실행
for n in numbers:
    print(n)
else:
    print("반복 완료!")   # 실행됨

# break로 탈출한 경우 → else 실행 안 됨
for n in numbers:
    if n == 3:
        break
else:
    print("반복 완료!")   # 실행 안 됨

예외처리의 try-else 와 같은 철학입니다.

else 실행 Oelse 실행 X
try-else예외 없이 정상 종료예외 발생
for-elsebreak 없이 정상 종료break로 탈출

실전 활용 - "찾으면 break, 못 찾으면 else" 패턴

# Java - 별도 flag 변수 필요
boolean found = false;
for (int n : numbers) {
    if (n == 3) { found = true; break; }
}
if (!found) System.out.println("못 찾았어요");
# Python - flag 변수 없이 깔끔하게
for n in numbers:
    if n == 3:
        break
else:
    print("못 찾았어요")  # break 없이 끝나면 실행


→ 2편에서 with, 함수, 클래스, 예외처리, import, Decorator, Generator 를 이어서 다룹니다.

profile
나의 기록

0개의 댓글