시퀀스 자료형
- 리스트(List): 변경 가능한 시퀀스 자료형.
- 튜플(Tuple): 변경 불가능한 시퀀스 자료형.
- 문자열(String): 변경 불가능한 시퀀스 자료형.
배열(array): 자료형 중 하나. type(array)를 해보자.
알고리즘 문제를 푸는데 있어서 반복문만큼이나 핵심적인 요소이다. 이거랑 반복문 알면 앵간한 문제 다 풀린다.
파이썬에는 배열을 특별히 리스트(list)라고 부른다. 다른 언어에서는 그냥 배열이라고 해서 존나게 헷갈린다. 리스트랑 배열이랑 같은건지 나도 방금 알았다. 강의에서는 그냥 배열이라고 하겠다.
배열이 왜 필요할까? 변수를 매우 많이 생성하고 싶을 때가 있다. 예를 들어 반 30명의 키를 모두 저장하고 싶은데, 변수를 일일이 지정하면 30줄이나 되는 코드가 필요하다. 이럴 때 유용한 것이 배열이다.
리스트를 만들어보자.
아래는 a라는 이름의 리스트이다.
튜플은 리스트의 차이점 중심으로 공부하면 편하다. 근데 튜플 쓸 일 별로 없더라.
요소 안에는 어떤 객체든 들어갈 수 있다
a = [38, 21, 53, 62, 19]
아래는 b라는 이름의 빈 리스트이다. 빈 리스트는 초기화 등에 많이 쓰인다. 저 빈 리스트에 요소를 추가하는 식으로 쓰인다. 숫자 말고 여러가지 객체를 넣을 수 있다. 빈 문자열, 문자열, 심지어 다른 리스트나 튜플도 넣을 수 있다!
*초기화
a= 0(ex)카운터)
b = []
b = list()
참고로 튜플은 대괄호 대신 소괄호를 이용하면 된다.
t1 = ()
t2 = (1,)
t3 = (1, 2, 3)
t4 = 1, 2, 3
t5 = ('a', 'b', ('ab', 'cd'))
모습은 리스트와 거의 비슷하지만, 튜플에서는 리스트와 다른 2가지 차이점을 찾아볼 수 있다. t2 = (1,)처럼 단지 1개의 요소만을 가질 때는 요소 뒤에 쉼표(,)를 반드시 붙여야 한다는 것과 t4 = 1, 2, 3처럼 소괄호(())를 생략해도 된다는 점이다.
이유:소괄호가 생략이 된 튜플인지, 객체 그 자체인지 구별이 힘들어서
공부할 때는 리스트를 위주로 하고,
튜플의 요솟값을 변경하려 하면 오류가 발생. 그러나 연결하기나 반복하기는 상관 없다.
아래와 같이 range를 사용해 만들 수도 있다.
a = list(range(10))
str함수, list 함수, tuple함수, float함수 등등.. 을 이용한거라고 생각.
시퀸스 객체 이용하기
이 부분은 시퀸스 객체라면 활용할 수 있다. 오늘은 배열만 배우지만 다른 시퀸스 자료형에도 잘 활용해보도록 하자.
특정 값이 있는지 확인하기
in
없는지 확인하기
not in
다른 언어에서는 for문을 통해서 판별
시퀸스 객체 연결하기
a+b로 한다. 이는 문자열 연결에서 해보았다. 단, range는 +연산자로 연결 할 수 없다. range로 리스트 또는 튜플을 만들어 연결하면 된다.(형변화)
시퀸스 객체 반복하기 단, range는 *연산자로 반복할 수 없다.
[0, 10, 20, 30] * 3
for문을 이용해 연결할 수도 있을 것이다. 실제로 파이썬이 아닌 다른 언어에서는 for반복문으로 연결하여야 한다.
시퀸스 객체 요소 개수 구하기
len()
인덱스(index색인) 사용하기
index란? 당연히 시퀀스에서만 가능하다.
*복습: 컴퓨터에서 숫자는 0부터 시작하는 것이 자연스럽다. 이유는 개수를 세기 편하고, 이진수의 특성상 0부터 시작이 자연스럽기 때문이다.
b = (38, 21, 53, 62, 19)
b에서 첫 번째 요소에 접근하고 싶으면 b[0], 두 번째 요소에 접근하려면 b[1]을 하면 된다. 당연히 튜플이나 문자열에도 된다. range도 가능은 하다.
대괄호는 배열 선언에도 쓰이고, 인덱스 접근에도 쓰인다. 혼동하지 말자.
여기서 마지막 요소를 접근하려고 하면 어떻게 해야할까?
b[len(b)-1]과 같은 거지 같은 코드를 짜야한다.
여기서 파이썬의 개쩌는 기능인 음수 인덱스가 나온다.
인덱스의 타입은 참조한 값의 자료형을 따른다.
>>> type(a[1])
<class 'int'>
위 사진과 같이 마지막 요소 접근을 하려면 a[-1]을 하면 된다. 마지막에서 2번째는 a[-2]이다.
근데 여기서 의문은 a[4]로 마지막 요소 접근을 하면 되지 왜 이렇게 뒤에서 읽어야 하냐는 것이다.
지금이야 배열의 원소(=요소)의 개수가 5개지만 동적(in other words 바뀔 수 있다면, to put in more simply 배열의 요소의 개수를 우리가 입력을 받는다면?)이라면 매우매우 유용한 방법이다.
다이나믹 배열에서는 배열 밖을 참조하게 되는 인덱세 에러를 조심하자.ex)배열이 3개로 input받았는데 index[5]f =>에러
b[len(b)-1]같은 코드를 쓰지 않게 해준 파이썬을 우리 모두 숭배하자. 파이썬 말고 음수 인덱스 있는 언어는 아직 못봤다.
위 코드에서 len을 생략한 것과 같은 모양이 음수 인덱스.
인덱스에서도 대괄호를 쓰고, 배열을 정의할 때도 대괄호를 써서 혼란스러울 수 있는데, 튜플이나 문자열에서도 대괄호로 인덱스 접근을 한다. 혼동하지 말도록 하자.
인덱스의 범위를 벗어나면 어떻게 될까? 한번 해보자.
요소에 값 할당하기
시퀀스객체[인덱스] = 값
이렇게 하면 바꿀 수 있다. 단 튜플은 안된다.
단, 범위를 벗어나면 인덱스가 추가된다고 생각할 수 있는데, 에러뜬다.
그래서 리스트를 확장하고 사용해야 한다. 또 동적 배열이기 때문에 여러 메서드를 사용할 수 있는데 조금 있다가 알아보자.
참고)자바스크립트는 인덱스가 추가된다.
요소에 값을 할당했으면 삭제도 된다.
- del 시퀀스객체[인덱스]
당연히 위 두개는 튜플에서는 불가하다.
아래는 추가로 알아두면 편리하다.
- append : 원소 마지막에 추가
>>> a = [1, 2, 3, 4, 5]
>>> a.append(6)
>>> a
[1, 2, 3, 4, 5, 6]
- insert : 리스트.index(입력할index, 값)
>>> a = [1, 2, 3]
>>> a.insert(1, 5)
>>> a
[1, 5, 2, 3]
- + 연산자로 더하기
>>> m = [2, 5, 7]
>>> n = [3, 5, 9]
>>> k = m + n
>>> k
[2, 5, 7, 3, 5, 9]
>>> k +=[11, 13]
>>> k
[2, 5, 7, 3, 5, 9, 11, 13]
- extend메소드 : 리스트.extend(추가할리스트)
>>> a = [1,2,3]
>>> a.extend([4,5,6])
>>> a
[1, 2, 3, 4, 5, 6]
- del 키워드를 통한 삭제
>>> a = [1, 2, 3, 4, 5, 6, 7]
>>> del a[1]
>>> a
[1, 3, 4, 5, 6, 7]
- list의 remove메소드에 의한 삭제
- list.remove(찾을아이템) #맨 앞만 지워야해
- 찾을 아이템이 없으면 ValueError 발생
>>> a = [1, 2, 3, 4, 5, 6, 7]
>>> a.remove(3)
>>> a
[1, 2, 4, 5, 6, 7]
>>> a.remove(9)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: list.remove(x): x not in list
- del키워드와 리스트의 index메소드와 혼합하여 사용하면 remove효과가 남
>>> a = [1, 2, 3, 4, 5, 6, 7]
>>> del a[a.index(3)]
>>> a
[1, 2, 4, 5, 6, 7]
아래는 연습문제이다.
다음 소스 코드를 완성하여 리스트 [5, 3, 1, -1, -3, -5, -7, -9]가 출력되게 만드세요. 리스트를 만들 때는 range를 사용해야 합니다.
practice_list.py
range
print(a)
실행 결과
[5, 3, 1, -1, -3, -5, -7, -9]
슬라이스, 슬라이싱
시퀸스 객체의 일부를 잘라낸다.
- 시퀀스객체[시작인덱스:끝인덱스] #range와 마찬가지로 끝-1까지만 가져온다.
>>> a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> a[0:4] # 인덱스 0부터 3까지 잘라서 새 리스트를 만듦
[0, 10, 20, 30]

슬라이스는 a[4:-1]과 같이 음수를 인덱스로 지정할 수도 있다.
>>> a[4:-1] # 인덱스 4부터 -2까지 요소 5개를 가져옴
[40, 50, 60, 70, 80]
인덱스 증가폭 이용하기
다음은 인덱스를 3씩 증가시키면서 요소를 가져온다. 여기서 주의할 점은 인덱스의 증가폭이지 요소의 값 증가폭이 아니라는 점이다.
- 시퀀스객체[시작인덱스:끝인덱스:인덱스증가폭]
>>> a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> a[2:8:3] # 인덱스 2부터 3씩 증가시키면서 인덱스 7까지 가져옴
[20, 50]
인덱스 생략하기
- 시퀀스객체[:끝인덱스]
>>> a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> a[:7] # 리스트 처음부터 인덱스 6까지 가져옴
[0, 10, 20, 30, 40, 50, 60]
- 시퀀스객체[시작인덱스:]
>>> a[7:] # 인덱스 7부터 마지막 요소까지 가져옴
[70, 80, 90]
- 시퀀스객체[:]
>>> a[:] # 리스트 전체를 가져옴
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
- 시퀀스객체[:끝인덱스:증가폭]
>>> a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> a[:7:2] # 리스트의 처음부터 인덱스를 2씩 증가시키면서 인덱스 6까지 가져옴
[0, 20, 40, 60]
- 시퀀스객체[시작인덱스::증가폭]
>>> a[7::2] # 인덱스 7부터 2씩 증가시키면서 리스트의 마지막 요소까지 가져옴
[70, 90]
- 시퀀스객체[::증가폭]
>>> a[::2] # 리스트 전체에서 인덱스 0부터 2씩 증가시키면서 요소를 가져옴
[0, 20, 40, 60, 80]
- 시퀀스객체[::]
>>> a[::] # 리스트 전체를 가져옴
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
len()을 응용하여 리스트 전체를 가져오기
>>> a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> a[0:len(a)] # 시작 인덱스에 0, 끝 인덱스에 len(a) 지정하여 리스트 전체를 가져옴
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> a[:len(a)] # 시작 인덱스 생략, 끝 인덱스에 len(a) 지정하여 리스트 전체를 가져옴
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
튜플과 문자열에서도 사용 가능하다.
아래는 참고.
슬라이스가 객첸지 나도 처음 알았다.
파이썬에서는 slice 객체를 사용하여 시퀀스 객체(시퀀스 자료형으로 만든 변수)를 잘라낼 수도 있습니다.
슬라이스객체 = slice(끝인덱스)
슬라이스객체 = slice(시작인덱스, 끝인덱스)
슬라이스객체 = slice(시작인덱스, 끝인덱스, 인덱스증가폭)
시퀀스객체[슬라이스객체]
시퀀스객체.__getitem__(슬라이스객체)
다음과 같이 시퀀스 객체의 [ ](대괄호) 또는 __getitem__ 메서드에 slice 객체를 넣어주면 지정된 범위만큼 잘라내서 새 객체를 만듭니다.
>>> range(10)[slice(4, 7, 2)]
range(4, 7, 2)
>>> range(10).__getitem__(slice(4, 7, 2))
range(4, 7, 2)
물론 slice 객체를 하나만 만든 뒤 여러 시퀀스 객체에 사용하는 방법도 가능합니다.
>>> a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> s = slice(4, 7) # 인덱스 4부터 6까지 자르는 slice 객체 생성
>>> a[s]
[40, 50, 60]
>>> r = range(10)
>>> r[s]
range(4, 7)
>>> hello = 'Hello, world!'
>>> hello[s]
'o, '
슬라이스에 요소 할당하기
- 시퀀스객체[시작인덱스:끝인덱스] = 시퀀스객체
먼저 리스트를 만든 뒤 특정 범위의 요소에 값을 할당해보겠습니다.
>>> a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> a[2:5] = ['a', 'b', 'c'] # 인덱스 2부터 4까지 값 할당
>>> a
[0, 10, 'a', 'b', 'c', 50, 60, 70, 80, 90]
a[2:5] = ['a', 'b', 'c']는 슬라이스 범위와 할당할 리스트의 요소 개수를 정확히 맞추었지만, 사실 개수를 맞추지 않아도 괜찮다.
다음과 같이 요소 개수를 맞추지 않아도 알아서 할당된다. 만약 할당할 요소 개수가 적으면 그만큼 리스트의 요소 개수도 줄어든다. 이것을 파이썬의 동적배열이라고 한다.
동적배열이란?
다른언어에서는 에러가 뜨거나, null값이 들어가는 경우도 있다.
>>> a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> a[2:5] = ['a'] # 인덱스 2부터 4까지에 값 1개를 할당하여 요소의 개수가 줄어듦
>>> a
[0, 10, 'a', 50, 60, 70, 80, 90]
반대로 할당할 요소가 많으면 리스트의 요소 개수도 그만큼 들어날 수 있다.
- 시퀀스객체[시작인덱스:끝인덱스:인덱스증가폭] = 시퀀스객체
>>> a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> a[2:8:2] = ['a', 'b', 'c'] # 인덱스 2부터 2씩 증가시키면서 인덱스 7까지 값 할당
>>> a
[0, 10, 'a', 30, 'b', 50, 'c', 70, 80, 90]
단, 인덱스 증가폭 지정시슬라이스 범위 요소 개수와 할당할 요소 개수가 정확히 일치해야 한다. 활용도가 떨어진다. 이런 점에서 파이썬은 일관성이 떨어진다.
- 시퀀스객체[시작인덱스:끝인덱스:인덱스증가폭] = 시퀀스객체
>>> a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> a[2:8:2] = ['a', 'b', 'c'] # 인덱스 2부터 2씩 증가시키면서 인덱스 7까지 값 할당
>>> a
[0, 10, 'a', 30, 'b', 50, 'c', 70, 80, 90]
튜플과 range, 문자열은 슬라이스 범위를 지정해도 요소 할당이 불가하다.
아래는 연습문제이다.
리스트 year에 연도, population에 서울시 인구수가 저장되어 있습니다. 다음 소스 코드를 완성하여 최근 3년간 연도와 인구수가 리스트로 출력되게 만드세요.
practice_slice.py
year = [2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018]
population = [10249679, 10195318, 10143645, 10103233, 10022181, 9930616, 9857426, 9838892]
print( )
print( )
실행 결과
[2016, 2017, 2018]
[9930616, 9857426, 9838892]
리스트 year에 연도, population에 서울시 인구수가 저장되어 있습니다. 다음 소스 코드를 완성하여 최근 3년간 연도와 인구수가 리스트로 출력되게 만드세요.
practice_slice.py
year = [2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018]
population = [10249679, 10195318, 10143645, 10103233, 10022181, 9930616, 9857426, 9838892]
print( )
print( )
실행 결과
[2016, 2017, 2018]
[9930616, 9857426, 9838892]
메소드 정리.
데이터를 다루는 함수들을 알아보자
1. len( )
len()은 문자열의 총길이를 구한다
2. count( )
count( )는 문자열 속에 일치하는 문자열의 개수를 반환한다
H를 세어보았을때 1을 반환한다
즉, 대,소문자를 구분하여 값을 반환한다.
3. find( ), rfind()
find( )는 해당 값이 최초로 시작되는 위치를 알려주며
해당 값이 발견되지 않을 시 -1을 반환한다.
4. index( )
find( )는 해당 값이 최초로 시작되는 위치를 알려주며
해당 값이 발견되지 않을 시 오류를 낸다. ( find( ) 와의 차이점 )
5. Join( )
문자열 사이사이에 구분자를 넣어준다
6. upper( ), lower( )
문자열을 대, 소문자로 바꿔준다
7. strip( ), lstrip( ), rstrip( )
strip( )은 앞뒤 공백을 지워준다.
lstrip( )은 앞 공백을 지워준다
rstrip( )은 뒤 공백을 지워준다
첫출력문과 rstrip() 결과와 같아보이지만 첫 출력은 뒤에 공백이 존재한다.
8. replace( )
원하는 기존 문자열을 새로운 새로운 문자열로 '치환'한다.
※변수. replace( '기존 값', '새로운 값' )
str1에서 치환작업을한 값을 str2로 담았다
str1자체를 '수정' 하는 것 처럼 보일 수 있지만
기존 데이터는 유지된다.
9. split( )
원하는 구분자로 하여 값을 나눈다
위와 마찬가지로 스플릿한 결과를 저장하고 싶다면
다른 변수에 결과를 담아줘야한다. (기존 변수는 값 유지)
그리고 타입 확인 결과 나누어진 데이터는 리스트 형태로 저장된다.
'파이썬 스터디' 카테고리의 다른 글
강의할 것 (0) | 2024.08.14 |
---|---|
파이썬 헷갈리는 것 (0) | 2024.06.03 |
2. 파이썬 기본문법 - 조건문과 반복문 (5) | 2024.05.27 |
1. 파이썬 기본 문법 자료형과 연산 (3) | 2024.05.12 |
IDE와 IDLE (0) | 2024.04.28 |