- List의 생성 및 조작
- List 내포(List Comprehension)의 특징
- Tuple의 생성 및 조작
- Tuple 내포(Tuple Comprehension)의 특징
- Q&A
- 마치며
- Sequence형
: 각 항목들에 대해 순서를 가진 자료구조의 총칭
ex) List, Tuple, ...
- 리스트(List)
:[]
안에 서로 다른 자료형의 값을,
로 구분해 하나 이상 저장할 수 있는 컬렉션 자료형
각 element는 0
부터 시작하는 index로 접근 가능합니다.
한 번 저장된 element는 변경할 수 있습니다.
(Tuple에서는 불가능했죠?🤔)
lst = [10, 21.5, "파이썬", True] # 선언 및 생성
print(f"{type(lst)} {lst}")
[Result]
<class 'list'> [10, 21.5, '파이썬', True]
- List의 항목 접근
- List의 기본 연산
- List의 항목 추가
- List의 항목 변경
- List의 항목 제거
- List의 항목 확인
- List와 for문 (List 객체의 개별 항목 접근법)
에 대해 각각 알아보겠습니다.
각 항목은 index를 이용해 접근 할 수 있습니다.
기본적으로 시작 index는 0
,
마지막 index는 (n-1)
입니다.
lst = [10, 20, 30, 40, 50]
print(f"lst[0] => {lst[0]}")
print(f"lst[4] => {lst[4]}")
[Result]
lst[0] => 10
lst[4] => 50
가장 오른쪽에 있는 index는 -1
,
가장 왼쪽에 있는 index는 -n
이 됩니다.
lst = [10, 20, 30, 40, 50]
print(f"lst[-5] => {lst[-5]}")
print(f"lst[-1] => {lst[-1]}")
[Result]
lst[-5] => 10
lst[-1] => 50
index를 지정할 때, :
을 이용하여 범위를 지정할 수도 있습니다.
하지만 이 경우, 마지막 범위는 포함되지 않습니다.
lst = [10, 20, 30, 40, 50]
print(f"lst[0:3] => {lst[0:3]}") # 0, 1, 2
[Result]
lst[0:3] => [10, 20, 30]
List의 내장함수 index()
는,
항목의 index를 반환합니다.
lst = [10, 20, 30, 40, 50]
print(f"lst.index(20) => {lst.index(20)}")
[Result]
lst.index(20) => 1
만약, 유효한 index가 아니라면, IndexError가 발생하니 주의해 주세요!
lst = [10, 20, 30, 40, 50]
print(f"lst[5] => {lst[5]}")
[Result]
IndexError: list index out of range
id()
함수는,
주소를 확인할 수 있습니다.
lst1, lst2 = [10, 20, 30], [40, 50]
print(f"lst1 : {hex(id(lst1))} {lst1}")
print(f"lst2 : {hex(id(lst2))} {lst2}")
[Result]
lst1 : 0x1b7994eb200 [10, 20, 30]
lst2 : 0x1b7994e6e40 [40, 50]
+
연산자를 이용해,
두 항목을 연결한 새로운 List를 만들 수 있습니다.
lst1, lst2 = [10, 20, 30], [40, 50]
print(f"lst1 + lst2 : {lst1 + lst2}")
[Result]
lst1 + lst2 : [10, 20, 30, 40, 50]
*
연산자를 이용해,
List를 반복적으로 연결하는 새로운 List를 만들 수 있습니다.
lst1, lst2 = [10, 20, 30], [40, 50]
print(f"lst1 * 2 : {lst1 * 2}")
[Result]
lst1 * 2 : [10, 20, 30, 10, 20, 30]
append()
함수를 이용한 항목 추가List의 내장함수 append()
함수는,
list의 마지막에 항목을 추가합니다.
반환값은 None
으로 없습니다.
lst = [10, 20, 30, 40]
lst.append(50) # 마지막에 '50' 추가
print(f"lst : {lst}")
[Result]
lst : [10, 20, 30, 40, 50]
inser()
함수를 이용한 항목 추가List의 내장함수 insert()
함수는,
list의 특정 위치에 항목을 추가합니다.
(리스트).insert(특정 index, 값)
lst = [10, 20, 30, 40]
lst.insert(2,20)
print(f"lst : {lst}")
[Result]
lst : [10, 20, 20, 30, 40]
extend()
함수를 이용한 항목 추가List의 내장함수 extend()
함수는,
list의 마지막에 또 다른 list의 항목을 추가합니다.
lst = [10, 20, 30, 40]
lst.extend([50, 60])
print(f"lst : {lst}")
[Result]
lst : [10, 20, 30, 40, 50, 60]
각 항목은 index를 이용해 변경 할 수 있습니다.
lst = [10, 20, 30, 40]
lst[3] = 50
print(f"lst : {lst}")
[Result]
lst : [10, 20, 30, 50]
index를 지정할 때, :
을 이용하여 범위를 지정할 수도 있습니다.
하지만 이 경우, 마지막 범위는 포함되지 않습니다.
lst = [10, 20, 30, 40]
lst[1:3] = [50, 60]
print(f"lst : {lst}")
[Result]
lst : [10, 50, 60, 40]
또한 지정된 범위보다 크거나 작은 List로 변경하면,
원래의 List 크기가 변경됩니다.
lst = [10, 20, 30, 40]
lst[1:3] = [50, 60, 70] # 범위보다 큰 List로 변경
print(f"lst : {lst}")
[Result]
lst : [10, 50, 60, 70, 40]
이처럼, 전체 List의 크기가 변경되었음을 알 수 있습니다.
del
명령어를 이용하여,
특정 index의 항목을 제거하거나,
특정 범위의 항목을 제거할 수 있습니다.
lst = [10, 20, 30, 40, 50]
del lst[1] # 특정 index의 항목 제거
print(f"lst : {lst}")
del lst[1:3] # 특정 범위의 항목 제거
print(f"lst : {lst}")
[Result]
lst : [10, 30, 40, 50]
lst : [10, 50]
pop()
함수를 이용한 제거List의 내장함수인 pop()
함수를 통해,
특정 index의 항목을 제거할 수 있습니다.
lst = [10, 20, 30, 40, 50]
lst.pop(1) # 1번째 index 항목 제거
print(f"lst : {lst}")
[Result]
lst : [10, 30, 40, 50]
remove()
함수를 이용한 제거List의 내장함수인 remove()
함수를 통해,
특정 값을 가지는 첫번째 항목을 제거할 수 있습니다.
lst = [10, 20, 30, 40, 50]
lst.remove(20)
print(f"lst : {lst}")
[Result]
lst : [10, 30, 40, 50]
clear()
함수를 이용한 제거List의 내장함수인 clear()
함수를 통해,
해당 List의 모든 항목을 제거할 수 있습니다.
lst = [10, 20, 30, 40, 50]
lst.clear()
print(f"lst : {lst}")
[Result]
lst : []
물론, del
명렁어와 범위연산자만 이용해 모든 항목을 제거할 수도 있습니다.
del lst[:]
이렇게용 😉
in
명령어를 통한 확인in
명령어를 통해,
List 객체에 해당 항목이 있는지 확인할 수 있습니다.
lst = [10, 20, 20, 20, 30, 40, 50]
print(f"20 in lst => {20 in lst}")
[Result]
20 in lst => True
반대로 없는지 검사하려면, not in
명령어를 사용할 수 있습니다.
count()
함수를 통한 항목의 개수 확인count()
함수룰 통해,
특정 항목의 개수를 확인할 수 있습니다.
lst = [10, 20, 20, 20, 30, 40, 50]
print(f"lst.count(20) => {lst.count(20)}")
[Result]
lst.count(20) => 3
만약, 해당 항목이 없다면 0
을 반환합니다.
lst = list(range(0, 11, 2))
for i in lst:
print(i, end = " ")
print()
for idx, val in enumerate(lst):
print(f"lst[{idx}] => {val}")
[Result]
0 2 4 6 8 10
lst[0] => 0
lst[1] => 2
lst[2] => 4
lst[3] => 6
lst[4] => 8
lst[5] => 10
for i in lst:
를 통해,
List의 항목을 반복해서 변수 i
에 저장합니다.
for idx, val in enumerate(lst):
를 통해,
List를 enumerateion 객체로 변환하고
index와 값을 반복해서 변수 idx
, val
에 저장합니다.
- List의 내포(List Comprehension)
: List의 선언 및 초기화 시 for문과 if문을 한 라인에 작성하는 방법(리스트) = [(표현식) for (변수) in (iterable 객체)] (리스트) = [(표현식) for (변수) in (iterable 객체) if (조건식)]
코드를 직관적이고, 실행 속도를 빠르게 해주는 장점이 있습니다.
iterable 자료형(List, Tuple, str, ...)의 경우,
리터럴 안에서 for문을 사용하면 내포 기능을 사용 할 수 있습니다.
다음의 예시를 한 번 보죠.
lst1 = [1, 2, 3, 4, 5]
lst2 = []
print(f"lst1 : {lst1}")
for i in lst1: # for문을 이용
lst2.append(i)
print(f"lst2 : {lst2}")
[Result]
lst1 : [1, 2, 3, 4, 5]
lst2 : [1, 2, 3, 4, 5]
for문을 통해 lst1
의 항목에 하나씩 접근해서 append()
함수로 lst2
에 추가했습니다.
그렇다면 List 내포(List Comprehesion)를 사용해 볼까요?
lst1 = [1, 2, 3, 4, 5]
lst2 = []
print(f"lst1 : {lst1}")
lst2 = [i for i in lst1] # List Comprehension
print(f"lst2 : {lst2}")
[Result]
lst1 : [1, 2, 3, 4, 5]
lst2 : [1, 2, 3, 4, 5]
lst2 = [i for i in lst1]
를 통해,
lst1
을 반복해서 참조하는 변수 i
의 값으로 이루어진 lst2
를 만들게 됩니다.
List 내포 기능을 사용할 때, 조건을 추가할 수도 있습니다.
아래의 예시는, for문과 if문을 통해 값을 lst2
에 전달하고 있습니다.
lst1 = [1, 2, 3, 4, 5]
lst2 = []
print(f"lst1 : {lst1}")
for i in lst1:
if i % 2 == 1: # 홀수라면
lst2.append(i)
print(f"lst2 : {lst2}")
[Result]
lst1 : [1, 2, 3, 4, 5]
lst2 : [1, 3, 5]
그렇다면 List 내포(List Comprehesion)를 사용해 볼까요?
lst1 = [1, 2, 3, 4, 5]
lst2 = []
print(f"lst1 : {lst1}")
lst2 = [i for i in lst1 if i % 2 == 1] # List Comprehension with condition
print(f"lst2 : {lst2}")
[Result]
lst1 : [1, 2, 3, 4, 5]
lst2 : [1, 3, 5]
List 내포 기능을 사용할 때, 중첩해서도 사용할 수 있습니다.
아래의 예시에서는, 반복 for문과 if문을 사용했습니다.
lst1 = [1, 2, 3, 4]
lst2 = []
for i in lst1:
if i % 2 == 1: # 홀수 항목
for j in lst1: # 중첩 for문
if j % 2 == 0: # 짝수 항목
lst2.append(i * j)
print(f"lst2 : {lst2}")
[Result]
lst2 : [2, 4, 6, 12]
(1 * 2)
, (1 * 4)
, (3 * 2)
,(3 * 4)
의 결과가 반환되었음을 알 수 있습니다.
그렇다면 List 내포(List Comprehesion)를 사용해 볼까요?
lst1 = [1, 2, 3, 4]
lst2 = []
# 중첩 List Comprehension with condition
lst2 = [i * j for i in lst1 if i % 2 == 1
for j in lst1 if j % 2 == 0]
print(f"lst2 : {lst2}")
[Result]
lst2 : [2, 4, 6, 12]
이처럼 List 내포(List Comprehension)를 사용하면,
for / if문보다 직관적이고, 짧고, 간결하며, 더 빠른 코드를 작성할 수 있습니다.
자주 등장하고 사용할 기능이니 꼭 알고 계셔야 합니다 😊
- 튜플(Tuple)
:()
안에 서로 다른 자료형의 값을,
로 구분해 하나 이상 저장할 수 있는 컬렉션 자료형
각 element는 0
부터 시작하는 index로 접근 가능합니다.
한 번 저장된 element는 변경할 수 없습니다.
(List는 가능했죠?🤔)
tpl = (10, 21.5, "파이썬", True) # 선언 및 생성
print(f"{type(tpl)} {tpl}")
[Result]
<class 'tuple'> (10, 21.5, '파이썬', True)
- Tuple의 항목 접근
- Tuple의 기본 연산
- Tuple의 항목 확인
- Tuple과 for문 (Tuple 객체의 개별 항목 접근법)
에 대해 각각 알아보겠습니다.
(참고로, Tuple은 element의 수정이 불가능하므로,
Tuple element에 대한 추가, 변경, 제거는 불가능합니다.)
각 항목은 index를 이용해 접근 할 수 있습니다.
기본적으로 시작 index는 0
,
마지막 index는 (n-1)
입니다.
tpl = (10, 20, 30, 40, 50)
print(f"tpl[0] => {tpl[0]}")
print(f"tpl[4] => {tpl[4]}")
[Result]
tpl[0] => 10
tpl[4] => 50
가장 오른쪽에 있는 index는 -1
,
가장 왼쪽에 있는 index는 -n
이 됩니다.
tpl = (10, 20, 30, 40, 50)
print(f"tpl[-5] => {tpl[-5]}")
print(f"tpl[-1] => {tpl[-1]}")
[Result]
tpl[-5] => 10
tpl[-1] => 50
index를 지정할 때,
:
을 이용하여 범위를 지정할 수도 있습니다.
하지만 이 경우, 마지막 범위는 포함되지 않습니다.
tpl = (10, 20, 30, 40, 50)
print(f"tpl[0:3] => {tpl[0:3]}") # 0, 1, 2
[Result]
tpl[0:3] => (10, 20, 30)
Tuple의 내장함수 index()
를 이용하여,
항목의 index를 알 수 있습니다.
tpl = (10, 20, 30, 40, 50)
print(f"tpl.index(20) => {tpl.index(20)}")
[Result]
tpl.index(20) => 1
만약, 유효한 index가 아니라면, IndexError가 발생하니 주의해 주세요!
tpl = (10, 20, 30, 40, 50)
print(f"tpl[5] => {tpl[5]}")
[Result]
IndexError: tuple index out of range
id()
함수를 통해,
주소를 확인할 수 있습니다.
tpl1, tpl2 = (10, 20, 30), (40, 50)
print(f"tpl1 : {hex(id(tpl1))} {tpl1}")
print(f"tpl2 : {hex(id(tpl2))} {tpl2}")
[Result]
tpl1 : 0x173cba400c0 (10, 20, 30)
tpl2 : 0x173cb706180 (40, 50)
+
연산자를 이용해,
두 항목을 연결한 새로운 Tuple을 만들 수 있습니다.
tpl1, tpl2 = (10, 20, 30), (40, 50)
print(f"tpl1 + tpl2 : {tpl1 + tpl2}")
[Result]
tpl1 + tpl2 : (10, 20, 30, 40, 50)
*
연산자를 이용해,
Tuple을 반복적으로 연결하는 새로운 Tuple을 만들 수 있습니다.
tpl1, tpl2 = (10, 20, 30), (40, 50)
print(f"tpl1 * 2 : {tpl1 * 2}")
[Result]
tpl1 * 2 : (10, 20, 30, 10, 20, 30)
in
명령어를 통한 확인in
명령어를 통해,
Tuple 객체에 해당 항목이 있는지 확인할 수 있습니다.
tpl = (10, 20, 20, 20, 30, 40, 50)
print(f"20 in tpl => {20 in tpl}")
[Result]
20 in tpl => True
반대로 없는지 검사하려면, not in
명령어를 사용할 수 있습니다.
count()
함수를 통한 항목의 개수 확인count()
함수룰 통해,
특정 항목의 개수를 확인할 수 있습니다.
tpl = (10, 20, 20, 20, 30, 40, 50)
print(f"tpl.count(20) => {tpl.count(20)}")
[Result]
tpl.count(20) => 3
만약, 해당 항목이 없다면 0
을 반환합니다.
tpl = tuple(range(0, 11, 2))
for i in tpl:
print(i, end = " ")
print()
for idx, val in enumerate(tpl):
print(f"tpl[{idx}] => {val}")
[Result]
0 2 4 6 8 10
tpl[0] => 0
tpl[1] => 2
tpl[2] => 4
tpl[3] => 6
tpl[4] => 8
tpl[5] => 10
for i in tpl:
를 통해,
tuple의 항목을 반복해서 변수 i
에 저장합니다.
for idx, val in enumerate(tpl):
를 통해,
tuple을 enumerateion 객체로 변환하고
index와 값을 반복해서 변수 idx
, val
에 저장합니다.
- Tuple의 내포(Tuple Comprehension)
: for문과 if문을 한 라인에 작성하는 방법(튜플) = [(표현식) for (변수) in (iterable 객체)] (튜플) = [(표현식) for (변수) in (iterable 객체) if (조건식)]
코드를 직관적이고, 실행 속도를 빠르게 해주는 장점이 있습니다.
iterable 자료형(List, Tuple, str, ...)의 경우,
리터럴 안에서 for문을 사용하면 내포 기능을 사용 할 수 있습니다.
Tuple 내포(Tuple Comprehesion)를 사용해 볼까요?
tpl1 = (1, 2, 3, 4, 5)
print(f"tpl1 : {tpl1}")
tpl_generator = (i for i in tpl1) # Tuple Comprehension을 통해 generator 객체 생성
tpl2 = tuple(tpl_generator) # generator 객체를 tuple 객체로 변환
print(f"tpl2 : {tpl2}")
[Result]
tpl1 : (1, 2, 3, 4, 5)
tpl2 : (1, 2, 3, 4, 5)
generator = (i for i in tpl1)
를 통해,
Tuple Comprehesion을 사용하여 generator 객체가 생성되었습니다.
그리고 생성된 generator 객체를 tuple()
함수를 사용하면,
실제 데이터 항목을 가진 Tuple 객체 tpl2
가 생성됩니다.
Tuple 내포 기능을 사용할 때, 조건을 추가할 수도 있습니다.
tpl1 = (1, 2, 3, 4, 5)
print(f"tpl1 : {tpl1}")
tpl2 = tuple(i for i in tpl1 if i % 2 == 1) # Tuple Comprehension with condition
print(f"tpl2 : {tpl2}")
[Result]
tpl1 : (1, 2, 3, 4, 5)
tpl2 : (1, 3, 5)
Tuple 내포 기능을 사용할 때, 중첩해서도 사용할 수 있습니다.
tpl1 = (1, 2, 3, 4)
# 중첩 Tuple Comprehension with condition
tpl2 = tuple(i * j for i in tpl1 if i % 2 == 1
for j in tpl1 if j % 2 == 0)
print(f"tpl2 : {tpl2}")
[Result]
tpl2 : (2, 4, 6, 12)
(1 * 2)
, (1 * 4)
, (3 * 2)
,(3 * 4)
의 결과가 반환되었음을 알 수 있습니다.
이처럼 Tuple 내포(Tuple Comprehension)를 사용하면,
for / if문보다 직관적이고, 짧고, 간결하며, 더 빠른 코드를 작성할 수 있습니다.
-
오늘은 저번에 변수를 다뤘던 글에서 등장했던
List와 Tuple에 대해 자세히 살펴봤습니다.
Iterable하며 Sequence한 Type의 가장 대표적인 자료구조인 List와 Tuple은 정말 다양하게 쓰일 수 있는 구조입니다.
각 자료형의 내장함수 및 활용법을 자세히 알고있는게 좋겠죠?
오늘 배웠던 내용만 잘 기억하고 있어도 웬만한 문제들은 해결할 수 있겠죠...?
그리고 또 다른 내용인 '내포'
사실, 문제를 풀다가 막히거나 다른 답과 비교하려고 구글링을 해보면 대부분 이 내포 기능을 사용하시더라구요.
근데 전 잘 몰랐어요ㅎㅎ 😊
(제가 1학년 때 파이썬을 배울 때도 교수님들이 가르쳐주신 기억이 없어요...)
(역시 컴공 공부는 혼자할 때 진정 빛나는 법이죠 😎)
그래서 이게 뭐지.. 어떻게 쓰는거야..
하면서 그냥 넘겼던 적이 많았거든요..
오늘로서 그럴 일은 없을 것 같네요.
사실 공부하면서 사용해보니까 너무 편한 기능이더라구요
이걸 왜 지금 안건지 😂
이제라도 배웠으니까, 잘 써봐야겠어요..
[Reference] : 위 글은 다음 내용을 참고, 인용하여 만들어졌습니다.
- 전반적 내용 : 삼성 SW Expert Academy