Python에서 시퀀스 객체는 순서가 있는 요소들의 집합입니다. 이들 객체는 고정된 순서를 가지며, 각 요소는 고유한 인덱스(색인)를 통해 접근할 수 있습니다. 인덱스는 두 가지 방식으로 부여됩니다.
- 양수 인덱싱: 시퀀스의 가장 왼쪽 요소부터 시작하며, 첫 번째 요소는 0, 두 번째는 1과 같이 양의 정수로 증가합니다.
- 음수 인덱싱: 시퀀스의 가장 오른쪽 요소부터 시작하며, 마지막 요소는 -1, 그 앞 요소는 -2와 같이 음의 정수로 감소합니다.
시퀀스 객체는 인덱스를 통해 개별 요소를 조작할 수 있지만, 모든 시퀀스가 동일한 수정 가능성을 가지는 것은 아닙니다. 예를 들어, 문자열(str)과 튜플(tuple)은 생성 후 내용을 변경할 수 없는 불변(immutable) 객체인 반면, 리스트(list)는 가변(mutable) 객체로 요소의 추가, 삭제, 변경이 가능합니다.
수학적 연산자 활용
Python 시퀀스 객체는 특정 수학적 연산자를 통해 다양한 작업을 수행할 수 있습니다.
덧셈 연산자 (+)
+ 연산자는 두 개의 동일한 타입 시퀀스를 연결(concatenation)하여 새로운 시퀀스를 반환합니다. 서로 다른 타입의 시퀀스나 시퀀스가 아닌 객체와는 연결할 수 없습니다.
# 올바른 예시: 같은 타입의 리스트 연결
list_a = [10, 20, 30]
list_b = [40, 50]
print(list_a + list_b) # 결과: [10, 20, 30, 40, 50]
# 올바른 예시: 같은 타입의 문자열 연결
str_a = "파이썬 "
str_b = "프로그래밍"
print(str_a + str_b) # 결과: 파이썬 프로그래밍
# 오류 예시: 다른 타입의 시퀀스 연결 시도 (리스트 + 정수)
try:
my_list = [1, 2]
num_val = 3
print(my_list + num_val)
except TypeError as e:
print(f"오류 발생: {e}") # 결과: 오류 발생: can only concatenate list (not "int") to list
복합 대입 연산자 (+=)
+= 연산자는 + 연산과 대입을 결합한 형태입니다. 기존 시퀀스에 다른 시퀀스를 연결한 후, 그 결과를 다시 원래 변수에 할당합니다. 문자열과 튜플의 경우 실제로는 새로운 객체를 생성하여 재할당하는 방식으로 동작합니다.
my_message = "안녕하세요, "
addition = "세상!"
my_message += addition
print(my_message) # 결과: 안녕하세요, 세상!
# 리스트의 경우
data_list = ['A', 'B']
more_data = ['C', 'D']
data_list += more_data # data_list가 [A, B, C, D]로 변경됨 (인플레이스 연산)
print(data_list) # 결과: ['A', 'B', 'C', 'D']
곱셈 연산자 (*)
* 연산자는 시퀀스를 지정된 횟수만큼 반복하여 새로운 시퀀스를 생성합니다.
# 튜플 반복 예시
pattern_tuple = (1, 'X')
repeated_tuple = pattern_tuple * 3
print(repeated_tuple) # 결과: (1, 'X', 1, 'X', 1, 'X')
# 문자열 반복 예시
separator = "-="
repeated_separator = separator * 5
print(repeated_separator) # 결과: -=-=-=-=-=
복합 대입 연산자 (*=)
*= 연산자는 * 연산과 대입을 결합합니다. 시퀀스를 반복한 후, 그 결과를 다시 원래 변수에 할당합니다.
my_string_part = "ABC"
my_string_part *= 2
print(my_string_part) # 결과: ABCABC
my_list_items = [7, 8]
my_list_items *= 3
print(my_list_items) # 결과: [7, 8, 7, 8, 7, 8]
비교 연산자 (<, >, == 등)
시퀀스 간의 비교는 요소들을 왼쪽에서 오른쪽으로 순차적으로 비교하여 수행됩니다. 첫 번째로 다른 요소에서 비교 결과가 결정됩니다. 요소들은 숫자 값으로 변환될 수 있다면 그렇게 비교되고, 문자열의 경우 사전식 순서(lexicographical order)로 비교됩니다. 서로 다른 타입의 시퀀스는 직접 비교할 수 없습니다.
# 튜플 비교 예시
tuple_data1 = (5, 10)
tuple_data2 = (5, 7)
print(f"{tuple_data1} > {tuple_data2} 결과: {tuple_data1 > tuple_data2}") # 결과: (5, 10) > (5, 7) 결과: True (두 번째 요소 10 > 7)
tuple_data3 = (3, 15)
tuple_data4 = (4, 5)
print(f"{tuple_data3} > {tuple_data4} 결과: {tuple_data3 > tuple_data4}") # 결과: (3, 15) > (4, 5) 결과: False (첫 번째 요소 3 < 4)
# 문자열 비교 예시
str_val1 = "apple"
str_val2 = "apricot"
print(f"{str_val1} < {str_val2} 결과: {str_val1 < str_val2}") # 결과: apple < apricot 결과: True ('p'와 'r' 비교)
# 다른 타입 비교 시 오류 발생
try:
list_val = [1, 'b']
tuple_val = (1, 'a')
print(list_val > tuple_val)
except TypeError as e:
print(f"오류 발생: {e}") # 결과: 오류 발생: '>' not supported between instances of 'list' and 'tuple'
멤버십 연산자 (in, not in)
in과 not in 연산자는 특정 요소나 부분 시퀀스가 다른 시퀀스 내에 존재하는지 여부를 확인합니다. 결과는 불리언 값(True 또는 False)으로 반환됩니다.
# 리스트 내 요소 확인
student_grades = ['A', 'B', 'C', 'A']
print(f"'B'가 목록에 있나요? {'B' in student_grades}") # 결과: 'B'가 목록에 있나요? True
print(f"'F'가 목록에 없나요? {'F' not in student_grades}") # 결과: 'F'가 목록에 없나요? True
# 문자열 내 부분 문자열 확인
full_text = "Python is powerful."
print(f"'Python'이 텍스트에 있나요? {'Python' in full_text}") # 결과: 'Python'이 텍스트에 있나요? True
print(f"'java'가 텍스트에 없나요? {'java' not in full_text}") # 결과: 'java'가 텍스트에 없나요? True
# 숫자와 문자열 비교 시 타입 불일치
try:
numeric_string = "12345"
print(123 in numeric_string) # 정수 123은 문자열 "12345"에 포함될 수 없음
except TypeError as e:
print(f"오류 발생: {e}") # 결과: 오류 발생: argument of type 'int' is not iterable
인덱싱 및 슬라이싱
시퀀스 객체의 특정 요소에 접근하거나 부분 시퀀스를 추출하는 데 사용됩니다.
인덱싱 (Indexing)
단일 인덱스를 사용하여 시퀀스의 특정 위치에 있는 요소를 가져옵니다. 앞서 설명했듯이, 양수 인덱스(0부터 시작)와 음수 인덱스(-1부터 시작)를 모두 사용할 수 있습니다. 불변 시퀀스(문자열, 튜플)의 요소는 인덱싱으로 변경할 수 없습니다.
my_sentence = "Coding is fun!"
print(f"첫 번째 문자: {my_sentence[0]}") # 결과: 첫 번째 문자: C
print(f"마지막 문자: {my_sentence[-1]}") # 결과: 마지막 문자: !
# 문자열 요소 변경 시도 (오류 발생)
try:
my_sentence[0] = 'D'
except TypeError as e:
print(f"오류 발생: {e}") # 결과: 오류 발생: 'str' object does not support item assignment
my_numbers = (100, 200, 300)
print(f"두 번째 숫자: {my_numbers[1]}") # 결과: 두 번째 숫자: 200
# 튜플 요소 변경 시도 (오류 발생)
try:
my_numbers[1] = 250
except TypeError as e:
print(f"오류 발생: {e}") # 결과: 오류 발생: 'tuple' object does not support item assignment
mutable_list = ['apple', 'banana', 'cherry']
print(f"기존 첫 번째 요소: {mutable_list[0]}") # 결과: 기존 첫 번째 요소: apple
mutable_list[0] = 'apricot' # 리스트는 변경 가능
print(f"변경된 첫 번째 요소: {mutable_list[0]}") # 결과: 변경된 첫 번째 요소: apricot
print(f"변경 후 리스트: {mutable_list}") # 결과: 변경 후 리스트: ['apricot', 'banana', 'cherry']
슬라이싱 (Slicing)
슬라이싱은 시퀀스의 일부분을 추출하여 새로운 시퀀스를 생성하는 강력한 기능입니다. 구문은 시퀀스[시작_인덱스:끝_인덱스:단계] 입니다.
시작_인덱스: 슬라이싱을 시작할 위치(포함). 기본값은0입니다.끝_인덱스: 슬라이싱을 끝낼 위치(불포함). 기본값은 시퀀스의 길이입니다.단계: 각 요소를 건너뛸 간격. 기본값은1입니다. 음수는 역순으로 슬라이싱합니다.
target_string = "Python_Programming_Language"
# 인덱스 0부터 6까지 (7은 미포함)
print(f"부분 문자열 1: {target_string[0:7]}") # 결과: 부분 문자열 1: Python_
# 인덱스 8부터 끝까지
print(f"부분 문자열 2: {target_string[8:]}") # 결과: 부분 문자열 2: Programming_Language
# 인덱스 0부터 10까지, 두 칸씩 건너뛰기
print(f"부분 문자열 3: {target_string[0:11:2]}") # 결과: 부분 문자열 3: Pto_P
# 인덱스 0: P, 2: t, 4: o, 6: _, 8: P, 10: o
# 음수 인덱스를 사용한 슬라이싱 (뒤에서 7번째부터 뒤에서 2번째까지, -1은 미포함)
print(f"부분 문자열 4: {target_string[-7:-1]}") # 결과: 부분 문자열 4: anguag
# 전체 시퀀스를 역순으로 (단계가 -1)
print(f"역순 문자열: {target_string[::-1]}") # 결과: 역순 문자열: egaugnaL_gnimmarogorP_nohtyP
Python 내장 함수
Python은 시퀀스 객체에 유용하게 사용될 수 있는 몇 가지 내장 함수를 제공합니다.
len(): 시퀀스의 요소 개수(길이)를 반환합니다.max(): 시퀀스 내에서 가장 큰 값을 반환합니다. 모든 요소가 비교 가능해야 합니다.min(): 시퀀스 내에서 가장 작은 값을 반환합니다. 모든 요소가 비교 가능해야 합니다.sum(): 시퀀스 내의 모든 숫자 요소를 더한 합계를 반환합니다. 시퀀스 요소는 반드시 숫자 타입이어야 합니다.
numbers = [10, 5, 20, 15]
characters = "hello"
scores = (90, 85, 95)
print(f"숫자 리스트의 길이: {len(numbers)}") # 결과: 숫자 리스트의 길이: 4
print(f"문자열 'hello'의 길이: {len(characters)}") # 결과: 문자열 'hello'의 길이: 5
print(f"최대 숫자: {max(numbers)}") # 결과: 최대 숫자: 20
print(f"최소 점수: {min(scores)}") # 결과: 최소 점수: 85
print(f"문자열 'hello'의 최대 문자: {max(characters)}") # 결과: 문자열 'hello'의 최대 문자: o (ASCII 값 기준)
print(f"숫자 리스트의 합계: {sum(numbers)}") # 결과: 숫자 리스트의 합계: 50
print(f"점수 튜플의 합계: {sum(scores)}") # 결과: 점수 튜플의 합계: 270
# 혼합 타입 시퀀스에 sum() 적용 시도 (오류 발생)
mixed_list = [1, 2, 'three']
try:
print(sum(mixed_list))
except TypeError as e:
print(f"오류 발생: {e}") # 결과: 오류 발생: unsupported operand type(s) for +: 'int' and 'str'