본문 바로가기
코딩테스트-파이썬

python 코테 관련 기능 정리 -Iterable(리스트(배열), 튜플, 집합(set))-

by 시니성 2023. 7. 22.

* Set 집합

중복되지 않은 자료들로 구성된 이터러블 객체 입니다.

순서가 없는 것이 특징입니다.

순서가 없기 때문에 인덱싱이 불가능 합니다.

 

* 교집합 연산(set)

`&` 연산자는 집합(Set)에 대한 교집합(intersection)을 구하는 연산자로, 집합의 원소들 중에서 공통으로 존재하는 원소들을 찾는데 사용됩니다.

만약 두 개의 리스트에 대해 교집합을 구하고자 한다면, 리스트를 집합으로 변환한 뒤 교집합 연산을 수행해야 합니다. 그러나 이러한 방법은 리스트의 순서를 무시하고 중복된 원소를 제거하게 됩니다.

예를 들어, 다음과 같이 두 개의 리스트가 있을 때:

list1 = [1, 2, 3, 4, 5]
list2 = [3, 4, 5, 6, 7]


두 리스트의 교집합을 구하고자 한다면 다음과 같이 할 수 있습니다:

set1 = set(list1)
set2 = set(list2)
intersection = set1 & set2
result = list(intersection)
print(result)  # 출력: [3, 4, 5]


위의 코드에서 `set(list1)`과 `set(list2)`를 사용하여 두 리스트를 집합으로 변환한 뒤, `&` 연산자로 교집합을 구합니다. 그리고 `list()` 함수를 사용하여 다시 리스트로 변환하여 결과를 출력합니다.

하지만 이 방법은 리스트의 순서를 무시하고 중복된 원소를 제거하는 문제가 있습니다. 따라서 교집합을 구할 때 리스트의 순서를 유지하고 중복을 제거하지 않는다면 다른 방법을 사용해야 합니다. 예를 들어 리스트 컴프리헨션 등을 사용하여 직접 구현하거나, `filter()` 함수를 이용하여 원하는 조건에 맞는 원소들을 추출하는 방법을 사용할 수 있습니다.

 

* 리스트와 튜플의 차이

  1. 변경 가능성(Immutable vs. Mutable):
    • 튜플(Tuple): 튜플은 변경 불가능한 자료형(immutable)입니다. 한 번 생성된 후에는 원소의 추가, 삭제, 수정이 불가능합니다.
    • 리스트(List): 리스트는 변경 가능한 자료형(mutable)입니다. 원소의 추가, 삭제, 수정이 가능합니다.
  2. 표기법:
    • 튜플: 원소들을 소괄호 ()로 둘러싸서 표현합니다. 예를 들면 (1, 2, 3)과 같이 사용합니다.
    • 리스트: 원소들을 대괄호 []로 둘러싸서 표현합니다. 예를 들면 [1, 2, 3]과 같이 사용합니다.
  3. 메모리 사용:
    • 튜플: 튜플은 변경 불가능하므로 한 번 생성되면 해당 튜플의 크기가 변경되지 않습니다. 따라서 일반적으로 리스트보다 더 작은 메모리를 사용합니다.
    • 리스트: 리스트는 변경 가능하므로 원소의 추가, 삭제 등으로 인해 크기가 동적으로 변할 수 있습니다.
  4. 사용 시점:
    • 튜플: 변경되지 않는 값을 저장하거나, 함수의 반환값으로 여러 개의 값을 반환할 때 주로 사용합니다.
    • 리스트: 데이터를 동적으로 관리하고자 할 때, 순서가 중요하고 중복을 허용하는 데이터들을 저장하고자 할 때 주로 사용합니다.
# 튜플 사용 예시
tuple_example = (1, 2, 3)
# tuple_example[0] = 100  # 오류 발생: 튜플은 변경 불가능

# 리스트 사용 예시
list_example = [1, 2, 3]
list_example[0] = 100  # 리스트는 변경 가능

 

* .append()

마지막 요소를 추가해 준다.

my_list = [1, 2, 3, 4]

# 마지막에 원소 5를 추가
my_list.append(5)

print(my_list)  # 출력: [1, 2, 3, 4, 5]

 

* num_list[ -1 ]

파이썬의 리스트 인덱싱은 음수 인덱싱이 가능하며,

-1의 경우 마지막 요소를 반환한다.

-2 의 경우 마지막 전 요소를 반환한다.

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

# 음수 인덱싱 사용
print(my_list[-1])  # 출력: 5 (가장 오른쪽 끝 요소)
print(my_list[-2])  # 출력: 4 (끝에서 두 번째 요소)
print(my_list[-3])  # 출력: 3 (끝에서 세 번째 요소)

 

* 언패킹

비구조화 할당과 유사한 기능입니다.

튜플, 리스트, 딕셔너리 등 다양한 자료구조들의 언패킹이 가능합니다.

주의할 점은 인덱스 길이보다 많은 변수로 할당하려 할 시 오류가 발생한다는 점입니다.

딕셔너리의 경우 키값에 없는 변수명으로 할당하려 할때에 오류가 발생한 다는 점을 유의하여야 합니다.

# 튜플 생성
my_tuple = (10, 20)

# 튜플 언패킹
a, b = my_tuple

print(a)  # 출력: 10
print(b)  # 출력: 20
# 리스트 언패킹
my_list = [10, 20, 30]
x, y, z = my_list

print(x)  # 출력: 10
print(y)  # 출력: 20
print(z)  # 출력: 30
my_list = [10, 20, 30]

# 변수의 개수가 리스트 길이보다 많은 경우 (ValueError 발생)
x, y, z, w = my_list  # ValueError: not enough values to unpack (expected 4, got 3)
# 딕셔너리 언패킹
my_dict = {'name': 'Alice', 'age': 30, 'city': 'New York'}
name, age, city = my_dict.values()

print(name)  # 출력: 'Alice'
print(age)   # 출력: 30
print(city)  # 출력: 'New York'
my_dict = {'name': 'Alice', 'age': 30}

# 딕셔너리 언패킹 시 존재하지 않는 키를 사용하는 경우 (NameError 발생)
name, age, city = my_dict.values()  # NameError: name 'city' is not defined

* 패킹

변수들을 특정 자료구조로 묶는것을 의미합니다.

# 변수들을 튜플로 패킹
x = 10
y = 20
z = 30
point = (x, y, z)

print(point)  # 출력: (10, 20, 30)

함수의 인자를 자동으로 패킹하는 기능을 제공합니다.

def my_function(*args):
    for arg in args:
        print(arg)

my_function(1, 2, 3)  # 출력: 1, 2, 3
def print_person_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

print_person_info(name='Alice', age=30, gender='female')
# 출력: name: Alice
#      age: 30
#      gender: female

* 파이썬에서의 스왑

tmp의 사용 없이 편하게 스왑할 수 있습니다.

my_list = [10, 20, 30, 40]

# 인덱스 1과 2에 해당하는 요소를 서로 교환
my_list[1], my_list[2] = my_list[2], my_list[1]

print(my_list)  # 출력: [10, 30, 20, 40]

 

* .count()

리스트에서 특정 요소의 개수를 세어 줍니다.

[].count(elem)

numbers = [1, 2, 2, 3, 4, 2, 5]
count_of_twos = numbers.count(2)
print(count_of_twos)  # 출력: 3

* .index(), .rindex()

리스트에서 특정 요소의 첫 번째 인덱스를 반환합니다.

존재하지 않는 요소의 인덱스 검색시 오류가 발생하므로 조심해야 합니다.

string의 경우 rindex가 존재하고 마지막 인덱스를 반환한다.

[].index(elem)

fruits = ['apple', 'banana', 'orange', 'apple', 'grape']
index_of_apple = fruits.index('apple')
print(index_of_apple)  # 출력: 0

* .find(), rfind()

인덱스와 동일하지만 존재하지 않을경우 -1을 반환한다.

스트링 에서만 사용 가능하다.

 

* map()

map(function, iterable)

이터러블의 각 엘리먼트에 함수를 적용한 결과를 반환합니다.

def square(x):
    return x ** 2

numbers = [1, 2, 3, 4, 5]
squared_numbers = map(square, numbers)

# map 객체를 리스트로 변환하여 결과 확인
result = list(squared_numbers)
print(result)  # 출력: [1, 4, 9, 16, 25]
numbers = [1, 2, 3, 4, 5]

# 람다 함수를 사용하여 각 숫자를 제곱하는 함수를 정의
squared_numbers = map(lambda x: x ** 2, numbers)

# map 객체를 리스트로 변환하여 결과 확인
result = list(squared_numbers)
print(result)  # 출력: [1, 4, 9, 16, 25]
text = ["apple", "banana", "orange", "grape"]
lengths = map(len, text)

# map 객체를 튜플로 변환하여 결과 확인
result = tuple(lengths)
print(result)  # 출력: (5, 6, 6, 5)

*슬라이싱으로 리스트 뒤집기

[::-1]

특정구간만 슬라이싱 떠서 뒤집는 예시코드는 아래와 같습니다

answer = ['a', 'b', 'c', 'd', 'e']
s, e = 1, 3

# answer[s:e+1]은 ['b', 'c', 'd']를 나타냅니다.
# [::-1]을 사용하여 리스트를 뒤집습니다. ['d', 'c', 'b']가 됩니다.
# 이후 answer[s:e+1] = ['d', 'c', 'b']가 되므로, answer는 ['a', 'd', 'c', 'b', 'e']가 됩니다.
answer[s:e+1] = answer[s:e+1][::-1]
print(answer)  # 출력: ['a', 'd', 'c', 'b', 'e']

 

* filter() 함수는 주어진 함수를 사용하여 iterable(반복 가능한 객체)의 요소들 중에서 조건을 만족하는 요소들로 이루어진 새로운 iterator(반복자)를 반환하는 내장 함수입니다.

filter(function, interable)

  • function: 필터링 조건을 판단하는 함수입니다. 이 함수는 True 또는 False를 반환해야 합니다.
  • iterable: 필터링을 적용할 iterable(반복 가능한 객체)입니다.

filter() 함수는 iterable의 각 요소에 대해 function을 호출하고, function의 반환값이 True인 요소들로 이루어진 새로운 iterator를 반환합니다.

# 짝수인지 판별하는 함수
def is_even(num):
    return num % 2 == 0

# 입력 리스트
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# is_even 함수를 사용하여 numbers 리스트에서 짝수만 필터링하여 새로운 iterator 생성
even_numbers = filter(is_even, numbers)

# 새로운 iterator를 리스트로 변환하여 결과 출력
print(list(even_numbers))  # 출력: [2, 4, 6, 8, 10]
# 입력 리스트
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# 람다 함수를 사용하여 numbers 리스트에서 짝수만 필터링하여 새로운 iterator 생성
even_numbers = filter(lambda x: x % 2 == 0, numbers)

# 새로운 iterator를 리스트로 변환하여 결과 출력
print(list(even_numbers))  # 출력: [2, 4, 6, 8, 10]

* [].sort와 sorted()

[].sort(func key, bool reverse)는 이터레이터의 값을 변환시키고 sorted([], func key, bool reverse)는 정렬된 새 이터레이터를 반환한다.

  • key: 정렬 기준으로 사용할 함수를 지정합니다. 기본값은 None으로, 리스트의 요소들을 기본적으로 크기 순서로 정렬합니다. key에 함수를 지정하면 해당 함수를 이용하여 리스트의 요소들을 비교하여 정렬합니다.
  • reverse: 정렬 순서를 지정합니다. 기본값은 False로, 오름차순으로 정렬합니다. True로 설정하면 내림차순으로 정렬합니다.
# 숫자 리스트 정렬 예시
numbers = [5, 2, 8, 1, 6, 3, 7, 4]

# 오름차순 정렬 (기본값)
numbers.sort()
print(numbers)  # 출력: [1, 2, 3, 4, 5, 6, 7, 8]

# 내림차순 정렬
numbers.sort(reverse=True)
print(numbers)  # 출력: [8, 7, 6, 5, 4, 3, 2, 1]

# 문자열 리스트 정렬 예시
fruits = ['apple', 'banana', 'orange', 'grape']

# 문자열 길이를 기준으로 정렬
fruits.sort(key=len)
print(fruits)  # 출력: ['grape', 'apple', 'banana', 'orange']

# 알파벳 역순으로 정렬
fruits.sort(key=lambda x: x[::-1])
print(fruits)  # 출력: ['banana', 'orange', 'grape', 'apple']
# 숫자 리스트 정렬 예시
numbers = [5, 2, 8, 1, 6, 3, 7, 4]

# 오름차순 정렬 (기본값)
sorted_numbers = sorted(numbers)
print(sorted_numbers)  # 출력: [1, 2, 3, 4, 5, 6, 7, 8]

# 내림차순 정렬
sorted_numbers_reverse = sorted(numbers, reverse=True)
print(sorted_numbers_reverse)  # 출력: [8, 7, 6, 5, 4, 3, 2, 1]

# 문자열 리스트 정렬 예시
fruits = ['apple', 'banana', 'orange', 'grape']

# 문자열 길이를 기준으로 정렬
sorted_fruits_length = sorted(fruits, key=len)
print(sorted_fruits_length)  # 출력: ['grape', 'apple', 'banana', 'orange']

# 알파벳 역순으로 정렬
sorted_fruits_reverse = sorted(fruits, key=lambda x: x[::-1])
print(sorted_fruits_reverse)  # 출력: ['banana', 'orange', 'grape', 'apple']

* sort, sorted key 자세히 알기

`sort()` 메서드의 `key` 인자는 파이썬 리스트(List)를 정렬할 때 사용하는 선택적인 인자입니다. 이 인자를 사용하면 리스트의 각 요소를 변형한 뒤에 해당 변형된 값을 기준으로 정렬할 수 있습니다. `key` 인자는 함수 혹은 람다 함수를 받으며, 이 함수의 반환값을 기준으로 정렬을 수행합니다.

`key` 인자를 사용하는 이유는 리스트에 복잡한 데이터 구조가 있을 때, 특정 필드를 기준으로 정렬하고 싶을 때 유용합니다. 예를 들어, 리스트가 딕셔너리로 구성되어 있고, 딕셔너리의 특정 키 값으로 정렬하고 싶을 때 `key` 인자를 사용하여 해당 키의 값을 추출하고 정렬할 수 있습니다.

`key` 인자의 사용 방법은 다음과 같습니다:

list.sort(key=None, reverse=False)

- `key`: 정렬 기준이 되는 함수나 람다 함수를 지정합니다. 기본값은 `None`이며, 이 경우 기본적으로 리스트의 요소 자체를 기준으로 정렬합니다.
- `reverse`: `True`로 설정하면 내림차순으로 정렬하고, 기본값인 `False`로 설정하면 오름차순으로 정렬합니다.

예를 들어:

# 정수 리스트를 절댓값의 오름차순으로 정렬하는 예시
my_list = [3, -1, 5, -2, 7, 4]
sorted_list = sorted(my_list, key=abs)
print(sorted_list)  # 출력: [-1, -2, 3, 4, 5, 7]

위의 예시에서 `key=abs`를 사용하여 리스트의 각 요소에 대해 `abs()` 함수를 적용하고, 이를 기준으로 리스트를 정렬하였습니다. `abs()` 함수는 절댓값을 반환하므로 결과적으로 절댓값의 오름차순으로 정렬된 리스트가 출력됩니다.

`key` 인자를 사용하면 정렬 기준을 유연하게 조작할 수 있으며, 데이터의 구조에 따라 원하는 방식으로 정렬할 수 있습니다.

* 다중 정렬키

정렬을 할 때, 두 개 이상의 정렬 키를 사용해야 하는 경우가 있습니다. 파이썬에서는 `sorted()` 함수 또는 리스트의 `.sort()` 메서드에서 `key` 인자로 두 개 이상의 정렬 키를 지정할 수 있습니다. 이러한 경우에는 `key` 인자에 함수 또는 람다 함수를 사용하여 여러 값을 반환하는 방법을 사용합니다.

여러 정렬 키를 사용하는 방법은 간단하게 람다 함수를 사용하여 튜플로 묶는 것입니다. 람다 함수를 통해 반환되는 튜플은 정렬에 사용되는 여러 값을 순서대로 나타내며, 정렬 알고리즘은 이러한 순서대로 리스트를 정렬합니다.

예를 들어, 다음과 같은 리스트를 이름(name)과 나이(age)로 구성된 튜플로 정렬하고 싶다고 가정해봅시다:

people = [("Alice", 25), ("Bob", 30), ("Charlie", 20), ("David", 35)]

이 리스트를 이름(name)을 기준으로 먼저 정렬하고, 이름이 같을 경우에는 나이(age)를 기준으로 정렬하려면 `key` 인자에 두 개의 값(name, age)을 반환하는 람다 함수를 사용할 수 있습니다:

sorted_people = sorted(people, key=lambda x: (x[0], x[1]))
print(sorted_people)


위의 예시에서 `key=lambda x: (x[0], x[1])`은 이름(name)과 나이(age)을 순서대로 반환하는 람다 함수를 의미합니다. 이 람다 함수는 각 튜플 `x`를 인자로 받아서 `(x[0], x[1])` 즉, 이름과 나이로 이루어진 튜플을 반환합니다. 따라서 정렬 키는 이름(name)으로 먼저 정렬하고, 이름이 같을 경우에는 나이(age)로 정렬하게 됩니다.

위의 예시를 실행하면 다음과 같은 결과를 얻을 수 있습니다:

[('Alice', 25), ('Bob', 30), ('Charlie', 20), ('David', 35)]


따라서 두 개 이상의 정렬 키를 사용하려면 람다 함수에서 튜플로 묶어서 반환하면 됩니다. 이를 통해 복잡한 정렬 기준을 쉽게 지정할 수 있습니다.

 

* enumerate(iterable, int start(=0))

순회 가능한(iterable) 객체(예: 리스트, 튜플, 문자열 등)를 입력으로 받아 각 요소와 인덱스를 포함하는 이터레이터(iterator)를 반환합니다. 이터레이터는 반복문에서 자주 사용되며, 요소의 값을 가져오는 동시에 해당 요소의 인덱스를 얻을 수 있게 해줍니다.

fruits = ['apple', 'banana', 'orange']

# enumerate를 사용하여 리스트의 요소와 인덱스를 출력
for index, fruit in enumerate(fruits):
    print(index, fruit)

* [-n] 슬라이싱

마지막 n개를 반환한다.

def solution(my_string, n):
    return my_string[-n:]

# 예시
my_string = "Hello, World!"
n = 5
result = solution(my_string, n)
print(result)  # 출력: "World!"

* 리스트 병합

리스트끼리 + 연산자를 통해 병합할 수 있다.

list1 = [1, 2, 3]
list2 = [4, 5, 6]

merged_list = list1 + list2

print(merged_list)  # Output: [1, 2, 3, 4, 5, 6]

 

* 리스트끼리의 대소 비교

파이썬에서는 리스트간 대소비교를 할 수 있습니다. 리스트간 대소비교는 사전 순서로 이루어지며, 첫 번째 원소부터 순차적으로 비교를 진행합니다. 만약 두 리스트의 첫 번째 원소가 같으면 다음 원소를 비교하고, 첫 번째 원소가 다르다면 첫 번째 원소의 대소를 기준으로 비교 결과를 결정합니다.

대소비교에서 사용하는 연산자는 <, <=, >, >=, ==, !=입니다.

예시 코드를 통해 이해해보겠습니다

list1 = [1, 2, 3]
list2 = [1, 2, 3]
list3 = [1, 2, 4]

# 리스트간 대소비교
print(list1 < list2)  # 출력: False (같음)
print(list1 <= list2)  # 출력: True (같음)
print(list1 > list3)  # 출력: False (작음)
print(list1 >= list3)  # 출력: False (작음)
print(list1 == list2)  # 출력: True (같음)
print(list1 != list3)  # 출력: True (다름)

 

* 중복 제거 방법

.set() 하지만 순서 유지가 되지 않습니다.

dict.fromkeys() 순서 유지가 된 상태로 중복제거가 됩니다.

728x90