03wk-1: 파이썬의 자료형 (4)

Author

최규빈

Published

March 20, 2023

강의영상

https://youtube.com/playlist?list=PLQqh36zP38-wtrnp6RqmbRVRrYVdualkl

list 고급내용 2

리스트 원소 추가

(예제) 비어있는 리스트를 만들고 원소 0,1,2를 차례로 추가하여 보자.

(풀이1) + 연산이용

a=[]
a
[]
a= a+[0]
a
[0]
a= a+[1] # a = [0]+[1]
a
[0, 1]
a= a+[2] # a = [0,1] + [2]
a
[0, 1, 2]

(풀이2) += 이용

a=[]
a+=[0]
a+=[1] 
a+=[2] 
a
[0, 1, 2]
  • 반복되는 문자를 제거하고 연산의 순서를 바꾼다.

(풀이3) 리스트 특수기능 .append()를 이용

a=[] 
a.append(0)
a.append(1)
a.append(2)
a
[0, 1, 2]

- 아래는 불가능하다.

a.append(0).append(1).append(2)
AttributeError: 'NoneType' object has no attribute 'append'
a.append(0,1,2)
TypeError: append() takes exactly one argument (3 given)

a+[4]a.append(4)의 차이점은?

(관찰1)

a=[1,2,3]
a+[4] ## 리스트 a와 리스트 [4]의 연산결과를 알려줘 
[1, 2, 3, 4]
a ## a는 그대로임. 변화없음 
[1, 2, 3]

(관찰2)

a=[1,2,3]
a.append(4)
a ## a자체가 변화함 
[1, 2, 3, 4]

비슷해보이지만 굉장히 미묘한 차이가 있음

a.append(4): a에 4를 append하라 \(\to\) a가 변함

a+[4]: a[4]를 연산하라

리스트 특수기능

(append)

a=[1,2,3,4]
a.append?
Signature: a.append(object, /)
Docstring: Append object to the end of the list.
Type:      builtin_function_or_method
a.append(5)
a
[1, 2, 3, 4, 5]

(clear)

a=[1,2,3,4]
a.clear?
Signature: a.clear()
Docstring: Remove all items from list.
Type:      builtin_function_or_method
a.clear()
a
[]

(copy)

a=[1,2,3,4]
a.copy?
Signature: a.copy()
Docstring: Return a shallow copy of the list.
Type:      builtin_function_or_method
b=a.copy()
b
[1, 2, 3, 4]

(count)

a=['a','a','b','b','b','c']
a.count?
Signature: a.count(value, /)
Docstring: Return number of occurrences of value.
Type:      builtin_function_or_method
a.count('a')
2
a.count('b')
3
a.count('c')
1

(extend)

a=[1,2,3,4]
b=[-1,-2,-3,-4]
a.extend(b)
a
[1, 2, 3, 4, -1, -2, -3, -4]
a=[1,2,3,4]
b=[-1,-2,-3,-4]
a.append(b)
a
[1, 2, 3, 4, [-1, -2, -3, -4]]

(index)

a=[11,22,'a',True, 22,'a']
a.index?
Signature: a.index(value, start=0, stop=9223372036854775807, /)
Docstring:
Return first index of value.
Raises ValueError if the value is not present.
Type:      builtin_function_or_method
a.index(11)
0
a.index(22)
1
a.index('a')
2
a.index(True)
3

(insert)

a=[1,2,3]
a.insert?
Signature: a.insert(index, object, /)
Docstring: Insert object before index.
Type:      builtin_function_or_method
a.insert(1,88) 
a
[1, 88, 2, 3]

(pop)

a=['a',1,2,'d']
a.pop?
Signature: a.pop(index=-1, /)
Docstring:
Remove and return item at index (default last).
Raises IndexError if list is empty or index is out of range.
Type:      builtin_function_or_method
a.pop() # index=-1 이므로 마지막원소가 나타남
'd'
a # a는 마지막 원소가 사라진 상태
['a', 1, 2]
a.pop(0) # index=0 이므로 첫번쨰 원소가 나타남
'a'
a # a에는 첫번째 원소가 사라진 상태
[1, 2]

(remove)

a=['a',2,3,'d']
a.remove?
Signature: a.remove(value, /)
Docstring:
Remove first occurrence of value.
Raises ValueError if the value is not present.
Type:      builtin_function_or_method
a.remove('d')
a
['a', 2, 3]
a.remove('a')
a
[2, 3]

(reverse)

a=[1,2,3,4]
a.reverse?
Signature: a.reverse()
Docstring: Reverse *IN PLACE*.
Type:      builtin_function_or_method
a.reverse()
a
[4, 3, 2, 1]

(sort)

a=[1,3,2,4]
a.sort?
Signature: a.sort(*, key=None, reverse=False)
Docstring:
Sort the list in ascending order and return None.
The sort is in-place (i.e. the list itself is modified) and stable (i.e. the
order of two equal elements is maintained).
If a key function is given, apply it once to each list item and sort them,
ascending or descending, according to their function values.
The reverse flag can be set to sort in descending order.
Type:      builtin_function_or_method
a.sort()
a
[1, 2, 3, 4]

(다른예제들)

a=list('guebin')
a
['g', 'u', 'e', 'b', 'i', 'n']
a.sort()
a
['b', 'e', 'g', 'i', 'n', 'u']
a.sort(reverse=True)
a
['u', 'n', 'i', 'g', 'e', 'b']

중첩리스트

- 리스트는 리스트를 원소로 받을 수 있으므로 아래와 같이 중첩된 리스트를 만들 수 있다.

A=[[1,2,3],
   [4,5,6],
   [7,8,9]]
A
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

- A는 1차원인 벡터가 아니라 2차원인 매트릭스로 이해할 수 있다. 구체적으로는 아래와 같은 매트릭스로 이해할 수 있다

$ \[\begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \end{bmatrix}\]

$

- A에서 (2,1)의 원소를 뽑고싶다 = 4를 뽑고싶다

A[1,0] # R에서는 이게 가능했죠
TypeError: list indices must be integers or slices, not tuple
  • 실패
A[1][0]
4
  • 성공

- 성공의 이유를 분석해보자.

A
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
A[1]
[4, 5, 6]
A[1][0]
4

- 매트릭스는 아니지만 매트릭스 같음! - 1차원 배열을 다차원 배열로 확장할 수 있는 기본 아이디어를 제공함

list 고급내용 3

- 리스트컴프리헨션을 다룬다.

예비학습1: for문 벼락치기

- 리스트 컴프리헨션을 이해하기 전에 for문에 대하여 알아보자.

프로그램안에서 반복해서 무엇인가를 하고싶다 \(\to\) for

for i in [0,1,2,3]: ## 반복실행계획
    print(i) ## 반복실행할내용, 탭을이용하여 들여쓰기해야한다. 
0
1
2
3

(예제) 1,2,3,4의 합을 for문을 이용하여 구해보자.

_sum = 0 
_sum = 0
for i in [1,2,3,4]: 
    _sum = _sum + i 
_sum
10
_sum = 0
i=1 
_sum = _sum + i ## 1 <= 0+1
i=2
_sum = _sum + i ## 3 <= 1+2 
i=3 
_sum = _sum + i ## 6 <= 3+3
i=4
_sum = _sum + i ## 10 <= 6+4 
_sum
10

- 궁금: 아래와 같은 코드가 있다고 하자.

for i in ????: 
    print(i)

??? 자리에 올 수 있는건 무엇일까?

  • 대답하기 어려움.
  • 일단 list는 가능했음.

(예시1)

for i in [1,2,3,4]: 
    print(i)
1
2
3
4

(예시2)

for i in ['a','b','c','d']: 
    print(i)
a
b
c
d

(예시3)

for i in 'abcd': 
    print(i)
a
b
c
d

(예시4)

for i in '1': 
    print(i)
1

(예시5)

for i in 1: 
    print(i)
TypeError: 'int' object is not iterable

(예시6)

for i in range(10): 
    print(i)
0
1
2
3
4
5
6
7
8
9

예비학습2: range

- range(0,10) 선언해보기

range(0,10)
range(0, 10)
  • 이게뭐야?

- 도움말 확인하기

_tmp = range(0,10)
_tmp?
Type:        range
String form: range(0, 10)
Length:      10
Docstring:  
range(stop) -> range object
range(start, stop[, step]) -> range object
Return an object that produces a sequence of integers from start (inclusive)
to stop (exclusive) by step.  range(i, j) produces i, i+1, i+2, ..., j-1.
start defaults to 0, and stop is omitted!  range(4) produces 0, 1, 2, 3.
These are exactly the valid indices for a list of 4 elements.
When step is given, it specifies the increment (or decrement).
  • 우리가 아는 범위에서는 모르겠음.. 이런게 있나보다 하고 넘어가야 하겠음

- 형태변환으로 range(0,10)의 느낌 찾기

list(range(0,10)) # 0을 포함, 10을 미포함 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  • 이게 중요한것임. range(0,10)를 리스트화시키면 [0,1,…,9] 와 같은 리스트를 얻을 수 있음. \(\Rightarrow\) range(0,10)은 [0,1,…,9] 와 “비슷한 것” 임

- range()의 활용

list(range(10)) # 0은 생략가능
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
list(range(2,10)) # 2는 포함, 10은 미포함 
[2, 3, 4, 5, 6, 7, 8, 9]
list(range(1,10,2)) # 2는 포함, 10은 미포함 
[1, 3, 5, 7, 9]

리스트 컴프리헨션

- 예제: \(2^0, 2^1, 2^2, 2^3\)를 원소로 가지는 리스트를 생성하라.

(풀이1) 직접입력

x= [2**0, 2**1, 2**2, 2**3] 
x
[1, 2, 4, 8]

(풀이2) for문을 이용함

x=[] 
for i in [0,1,2,3]:
    x.append(2**i) 
x
[1, 2, 4, 8]

(풀이3) for문을 이용함

x=[] 
for i in [0,1,2,3]:
    x = x+[2**i]
x
[1, 2, 4, 8]

(풀이4) for문을 이용함

x=[] 
for i in [0,1,2,3]:
    x += [2**i]
x
[1, 2, 4, 8]

(풀이5) 리스트컴프리헨션을 이용한 풀이

[2**i for i in [0,1,2,3]]
[1, 2, 4, 8]

- 리스트컴프리헨션의 문법 암기방법

  • 집합에서 조건제시법을 연상
  • \(\{2^0,2^1,2^2,2^3\}=\{2^i: i \in \{0,1,2,3\} \}\)

- 리스트컴프리헨션이란?

  • 리스트를 매우 효율적으로 만드는 테크닉
  • for문에 비하여 가지고 있는 장점: (1) 코드가 간결하다 (2) 빠르다

리스트 컴프리헨션 연습

- 예제1: 리스트 컴프리헨션을 이용하여 아래와 같은 리스트를 만들어라.

['SSSS','PPPP','AAAA','MMMM']
['SSSS', 'PPPP', 'AAAA', 'MMMM']

(풀이)

[i*4 for i in 'SPAM']
['SSSS', 'PPPP', 'AAAA', 'MMMM']

- 예제2: 리스트컴프리헨션을 이용하여 아래와 같은 리스트를 만들어라.

['X1','X2','X3','Y1','Y2','Y3']
['X1', 'X2', 'X3', 'Y1', 'Y2', 'Y3']

(풀이)

[i+j for i in 'XY' for j in '123']
['X1', 'X2', 'X3', 'Y1', 'Y2', 'Y3']

- 예제: 리스트컴프리헨션을 이용하여 아래와 같은 리스트를 만들어라.

['stat1', 'stat2', 'stat3', 'math1', 'math2', 'math3']
['stat1', 'stat2', 'stat3', 'math1', 'math2', 'math3']

(풀이)

[i+j for i in ['stat', 'math'] for j in '123']
['stat1', 'stat2', 'stat3', 'math1', 'math2', 'math3']

(다른풀이) 참고로 for문을 쓰면 좀 복잡해진다.

_lst = [] 
for x in ['stat','math']: 
    for y in '123': 
        _lst = _lst + [x+y] 
_lst 
['stat1', 'stat2', 'stat3', 'math1', 'math2', 'math3']

- 예제: 리스트컴프리헨션과 문자열 'jbnu'를 이용하여 아래와 같은 리스트를 만들어라.

['j','b','n','u']
['j', 'b', 'n', 'u']

(다른풀이) 아래와 같이 풀면 된다는것은 알고 있음

list('jbnu')
['j', 'b', 'n', 'u']

(풀이)

[i for i in 'jbnu']
['j', 'b', 'n', 'u']

- 예제: 리스트컴프리헨션을 이용하여 아래와 같은 리스트를 만들어라.

['X1', 'X2', 'X3', 'X4', 'X5', 'X6', 'X7', 'X8', 'X9', 'X10', 'X11', 'X12']
['X1', 'X2', 'X3', 'X4', 'X5', 'X6', 'X7', 'X8', 'X9', 'X10', 'X11', 'X12']

(풀이)

['X'+str(i) for i in range(1,13)]
#['X'+str(i) for i in list(range(1,13))]
['X1', 'X2', 'X3', 'X4', 'X5', 'X6', 'X7', 'X8', 'X9', 'X10', 'X11', 'X12']

리스트 컴프리헨션과 for문의 미묘한 차이

(경우1)

x=777 
lst = [] 
for x in 'jbnu': 
    lst = lst + [x]
lst    
['j', 'b', 'n', 'u']
x
'u'

(경우2)

x=777
lst = [x for x in 'jbnu'] 
lst 
['j', 'b', 'n', 'u']
x
777

진짜 미묘하게 다르죠?

튜플 기본내용

리스트 vs 튜플

- 컨테이너형타입이라는 점, 그리고 연산 및 인덱싱을 하는 방법은 리스트와 같음 - 차이점1: [] 대신에 ()를 사용한다. - 차이점2: 불변형이다. (원소의 값을 바꿀 수 없음) - 차이점3: 하나의 원소를 선언할 때는 (1,)와 같이 해야 한다. - 차이점4: 의미가 명확할때는 튜플의 ()를 생략가능하다.

- 컨테이너형이라는 것이 무슨의미?

a=(4,6,'pencil', 3.2+4.6j, [3,4]) 
type(a[2])
str
type(a[3])
complex

- 불변형이라는 것은 무슨의미?

a[2] = 'Pencil'
TypeError: 'tuple' object does not support item assignment

참고로 a를 튜플이 아니라 리스트로 선언하면 값이 잘 바뀐다.

a=[4,6,'pencil', 3.2+4.6j, [3,4]]
a[2]
'pencil'
a[2]='Pencil'
a
[4, 6, 'Pencil', (3.2+4.6j), [3, 4]]

- 하나의 원소로 이루어진 튜플을 만들때는 쉼표를 붙여야 함.

[1]+[2,3,4]
[1, 2, 3, 4]
(1,)+(2,3,4)
(1, 2, 3, 4)

- 마지막차이점! 의미가 명확할때 튜플의 괄호는 생략가능하다. (이게 중요합니다)

a=1,2
a
(1, 2)

의미가 명확할때 생략해야함

1,2 + 3,4,5 
(1, 5, 4, 5)
(1,2) + (3,4,5) 
(1, 2, 3, 4, 5)

선언

- 소괄호를 이용

a=(1,2,3)
a
(1, 2, 3)
type(a)
tuple

- 생략가능하다는 점이 포인트

a=1,2,3
a
(1, 2, 3)
type(a)
tuple

- 원소가 하나인 튜플을 만들고 싶다면?

a=(1,)
a
(1,)

연산

- 리스트와 동일

(1,2)+(3,4,5)
(1, 2, 3, 4, 5)
(1,2)*2
(1, 2, 1, 2)

인덱싱

- 리스트와 동일

a=(1,2,3,-4,-5)
a
(1, 2, 3, -4, -5)
a[-1]
-5
a[-3:]
(3, -4, -5)

HW 0320

1. 아래의 코드를 관찰하고, sum()의 기능을 유추하라.

sum([1,0,1,0])
2
sum([True,False,True,False])
2

(풀이)

생략

2. 다음과 같은 리스트를 고려하자.

x = [80,60,80,90,55,85,95,100,35,70,75,65,95]
x
[80, 60, 80, 90, 55, 85, 95, 100, 35, 70, 75, 65, 95]

이를 수식으로 표현하면 아래와 같다.

\({\bf x} = [x_1,\dots,x_{13}]=[80,60,80,90,55,85,95,100,35,70,75,65,95]\)

리스트의 원소중 “\(x_i>80\)” 의 조건을 만족하는 원소는 모두 몇개인가?

hint: 리스트컴프리헨션과 sum()함수를 이용할 것

(풀이)

sum([xi >80 for xi in x])
5

3. 다음과 같은 리스트를 고려하자.

['A','B','C','D','A','A','B','A','F','C','C','C','A']
['A', 'B', 'C', 'D', 'A', 'A', 'B', 'A', 'F', 'C', 'C', 'C', 'A']

이 리스트에서 ‘A’ 혹은 ’B’의 숫자는 모두 몇개인가?

hint: 아래를 관찰

'A' < 'C'
True
'B' < 'C'
True

(풀이)

lst = ['A','B','C','D','A','A','B','A','F','C','C','C','A']
sum([l <'C' for l in lst])
7

4. 아래와 같은 리스트가 있다고 하자.

\({\bf x} = [1,2,1,5,6,2,4,7]\)

\({\bf y} = [3,2,4,1,2,5,6,7]\)

이러한 벡터를 파이썬에서 표현하기 위해서 아래와 같은 리스트를 만들었다고 하자.

x=[1,2,1,5,6,2,4,7]
y=[3,2,4,1,2,5,6,7] 

리스트컴프리헨션을 이용하여

\[{\bf z}=[x_1^2+y_1^2, \dots, x_{8}^2+y_{8}^2]=[x_i^2+y_i^2: \text{for $i = 1,2,3,\dots,8$}]\]

와 같은 리스트를 생성하라.

(풀이)

[x[i]**2+y[i]**2 for i in range(8)]
[10, 8, 17, 26, 40, 29, 52, 98]

5. 아래와 같은 문자열이 있다고 하자.

test_arr = 'ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSUGPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XAt3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/EnmZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbxNrRFi9wrf+M7Q== schacon@mylaptop.local'

이 문자열에서 대문자의 수를 count하라. (2022년 파이썬입문 중간고사 1-(5) 참고)

(풀이)

sum([s.isupper() for s in test_arr ])
155

6. 리스트컴프리헨션을 이용하여 아래와 같은 리스트를 생성하라. (2022년 파이썬입문 중간고사 1-(7) 참고)

['a',
 'aa',
 'aaa',
 'aaaa',
 'aaaaa',
 'aaaaaa',
 'aaaaaaa',
 'aaaaaaaa',
 'aaaaaaaaa',
 'aaaaaaaaaa'] <- a가 10개있음

(풀이)

['a'*i for i in range(1,11)]
['a',
 'aa',
 'aaa',
 'aaaa',
 'aaaaa',
 'aaaaaa',
 'aaaaaaa',
 'aaaaaaaa',
 'aaaaaaaaa',
 'aaaaaaaaaa']

7. 아래와 같은 list가 있다고 하자.

test_lst = [['g',1],['u',5],['e',2],['b',8],['i',2],['n',9]]

test_lst와 리스트컴프리헨션을 이용하여 아래를 출력하는 코드를 구현하라. (2022년 파이썬입문 중간고사 1-(9) 참고)

['g', 'uuuuu', 'ee', 'bbbbbbbb', 'ii', 'nnnnnnnnn']
['g', 'uuuuu', 'ee', 'bbbbbbbb', 'ii', 'nnnnnnnnn']

(풀이)

[l[0]*l[1] for l in test_lst]
['g', 'uuuuu', 'ee', 'bbbbbbbb', 'ii', 'nnnnnnnnn']

8. 아래와 같은 list를 생성하라.

[1,
 2,2,
 3,3,3,
 4,4,4,4,
 5,5,5,5,5,
 ...
 9,9,9,9,9,9,9,9,9] <- 9 9 있음 

(풀이1) – 의도한 풀이

lst = list()
for i in range(1,10):
    lst = lst + [i]*i

(풀이2) – 이걸 의도한건 아니었음…

lst = [[i]*i for i in range(1,10)]
print(str(lst).replace(' ','').replace(',[','').replace(']',',\n ').replace('[[','[').replace(',\n ,',']'))
[1,
 2,2,
 3,3,3,
 4,4,4,4,
 5,5,5,5,5,
 6,6,6,6,6,6,
 7,7,7,7,7,7,7,
 8,8,8,8,8,8,8,8,
 9,9,9,9,9,9,9,9,9]
 

9. 아래와 같은 리스트를 관찰하라.

lst = ['2022/09/21','2022/10/30','2022/12/25','2023/01/01','2023/01/31','2023/03/20']

이러한 리스트를 아래와 같은 리스트로 변환하는 코드를 작성하라.

['2022-09-21', '2022-10-30', '2022-12-25', '2023-01-01', '2023-01-31', '2023-03-20']
['2022-09-21',
 '2022-10-30',
 '2022-12-25',
 '2023-01-01',
 '2023-01-31',
 '2023-03-20']

hint: string의 .replace()기능과 리스트 컴프리헨션의 응용

(풀이)

[s.replace('/','-') for s in lst]
['2022-09-21',
 '2022-10-30',
 '2022-12-25',
 '2023-01-01',
 '2023-01-31',
 '2023-03-20']

10. 아래와 같은 문자열을 고려하라.

'2021. 01. 05.'
'2021. 01. 05.'

띄어쓰기를 제거하는 코드를 구현하라. 즉 출력결과가 아래와 같도록 만드는 코드를 구현하라.

'2021.01.05'
'2021.01.05'

hint: 아래코드 관찰

'asdf'.replace('a','')
'sdf'

(풀이)

'2021. 01. 05.'.replace(' ','')
'2021.01.05.'

11. 아래의 코드를 관찰하라.

'-'.join(['2022','01','05'])
'2022-01-05'
'.'.join(['2022','01','05'])
'2022.01.05'

ChatGPT를 이용하여 이 코드가 의미하는 내용을 유추하라.

(풀이)

생략

12. 아래와 같이 하나의 특수문자로 이루어진 리스트를 고려하자.

block = ['■'] 

이를 이용하여 아래와 같은 결과를 출력하라.

'■-■-■-■-■-■-■-■-■-■' # 여기에서 '■'는 모두 10개 있음
'■-■-■-■-■-■-■-■-■-■'

hint: 11번 문제의 코드를 응용할 것

(풀이)

'-'.join(block*10)
'■-■-■-■-■-■-■-■-■-■'