기본 자료형: 리스트

μ•ˆλ‚΄: Think Python 10μž₯ λ‚΄μš©μ˜ 일뢀λ₯Ό λ²ˆμ—­ 및 μš”μ•½μˆ˜μ •ν•˜μ—¬ μ •λ¦¬ν•œ λ‚΄μš©μž…λ‹ˆλ‹€.

파이썬 ν”„λ‘œκ·Έλž˜λ°μ–Έμ–΄λŠ” μ •μˆ˜, μ‹€μˆ˜, 진리값(bool) λ“±μ˜ κΈ°λ³Έ μžλ£Œν˜• 이외에 리슀트(list), λ¬Έμžμ—΄(str), νŠœν”Œ(tuple), 집합(set), 사전(dict) λ“± μ—¬λŸ¬ 개의 값듀을 λ¬Άμ–΄μ„œ ν•˜λ‚˜μ˜ κ°’μœΌλ‘œ μ·¨κΈ‰ν•˜λŠ” λͺ¨μŒ(collection) μžλ£Œν˜•μ„ μ œκ³΅ν•œλ‹€. λͺ¨μŒ μžλ£Œν˜•μ€ μ»¨ν…Œμ΄λ„ˆ(container) μžλ£Œν˜•μœΌλ‘œ λΆˆλ¦¬κΈ°λ„ ν•œλ‹€.

λͺ¨μŒ μžλ£Œν˜•μ€ 크게 두 μ’…λ₯˜λ₯΄ κ΅¬λΆ„λœλ‹€.

  • ν•­λͺ©λ“€ 사이에 μˆœμ„œκ°€ μžˆλŠ” μžλ£Œν˜•: λ¬Έμžμ—΄, 리슀트, νŠœν”Œ
  • ν•­λͺ©λ“€ 사이에 μˆœμ„œκ°€ μ—†λŠ” μžλ£Œν˜•: 집합, 사전

μ—¬κΈ°μ„œλŠ” 파이썬이 μ œκ³΅ν•˜λŠ” μžλ£Œν˜• μ€‘μ—μ„œ κ°€μž₯ μœ μš©ν•œ 리슀트 μžλ£Œν˜•μ„ 닀룬닀.

순차(서열) 자료형: 리스트

λ¦¬μŠ€νŠΈμ— ν¬ν•¨λ˜λŠ” κ°’λ“€ μ‚¬μ΄μ˜ μˆœμ„œλŠ” μ ˆλŒ€μ μœΌλ‘œ μ€‘μš”ν•˜λ‹€. ν•­λͺ©λ“€μ˜ μˆœμ„œ, ν•­λͺ©λ“€ μ‚¬μ΄μ˜ 순차(μ„œμ—΄)이 μ€‘μš”ν•˜λ‹€λŠ” 의미둜 리슀트 μžλ£Œν˜•μ„ 순차(μ„œμ—΄) μžλ£Œν˜•μ— ν¬ν•¨μ‹œν‚¨λ‹€. 순차(μ„œμ—΄) μžλ£Œν˜•μ„ μ‹œν€€μŠ€(sequence) μžλ£Œν˜•μ΄λΌκ³  λΆ€λ₯΄κΈ°λ„ ν•œλ‹€.

리슀트의 ν˜•μ‹μ€ λ‹€μŒκ³Ό κ°™λ‹€.

[ ν•­λͺ©1, ν•­λͺ©2, ..., ν•­λͺ©n ]

μ•„λž˜ μ˜ˆμ œμ™€ 같이 μˆœμ„œ λ˜λŠ” ν•­λͺ©μ˜ κ°œμˆ˜κ°€ λ‹€λ₯΄λ©΄ μ„œλ‘œ λ‹€λ₯΄λ‹€κ³  μ²˜λ¦¬λœλ‹€.

In [1]:
[1, 3] == [3, 1]
Out[1]:
False
In [2]:
[1] != [1,1]
Out[2]:
True

리스트 자료형의 주요 특징

리슀트의 ν•­λͺ©μœΌλ‘œ μž„μ˜μ˜ 값이 올 수 있으며, ν•­λͺ©λ“€μ˜ μžλ£Œν˜•μ΄ 달라도 λœλ‹€. λ”°λΌμ„œ, 리슀트 ν•­λͺ©μœΌλ‘œ λ‹€λ₯Έ λ¦¬μŠ€νŠΈκ°€ μ‚¬μš©λ  μˆ˜λ„ μžˆλ‹€.

In [3]:
a_list = ['spam', 2.0, 5, [10, 20], True]

ν•­λͺ©μ΄ μ „ν˜€ μ—†λŠ” λΉ„μ–΄ μžˆλŠ” 리슀트인 빈 λ¦¬μŠ€νŠΈλŠ” []둜 ν‘œμ‹œλœλ‹€.

In [4]:
print(type([]))
<class 'list'>

λ¬Όλ‘  리슀트λ₯Ό λ³€μˆ˜μ— ν• λ‹Ήν•  μˆ˜λ„ μžˆλ‹€.

In [5]:
myList = [1, 2, True, 6.5, "abc"]
print(myList)
[1, 2, True, 6.5, 'abc']

리스트 관련 함수

리슀트 μžλ£Œν˜•μ€ κ°€μž₯ 많이 μ‚¬μš©λ˜λŠ” μžλ£Œν˜•μΈ 만큼 λ¦¬μŠ€νŠΈμ™€ κ΄€λ ¨λœ λ‹€μ–‘ν•œ ν•¨μˆ˜λ“€μ΄ μ‘΄μž¬ν•œλ‹€. 특히 μ•„λž˜μ— μ†Œκ°œλœ ν•¨μˆ˜λ“€μ€ 리슀트λ₯Ό ν¬ν•¨ν•˜μ—¬ λͺ¨λ“  순차(μ„œμ—΄) μžλ£Œν˜•μ΄ κ³΅ν†΅μ μœΌλ‘œ μ‚¬μš©λ˜λ©°, λ¬Έμžμ—΄ μžλ£Œν˜•μ—μ„œ μ†Œκ°œν•œ 방식과 λ™μΌν•˜κ²Œ μž‘λ™ν•œλ‹€.

  • [k] : 인덱싱
  • [i:j:k]: μŠ¬λΌμ΄μ‹±
  • + : 이어 뢙이기(concatenation)
  • * : λ°˜λ³΅ν•΄μ„œ 이어뢙이기
  • in : ν•­λͺ© 포함여뢀 확인
  • len : ν•­λͺ© 개수 확인
In [6]:
myList[0]
Out[6]:
1
In [7]:
myList[1:5:2]
Out[7]:
[2, 6.5]
In [8]:
myList + a_list
Out[8]:
[1, 2, True, 6.5, 'abc', 'spam', 2.0, 5, [10, 20], True]
In [9]:
myList * 2
Out[9]:
[1, 2, True, 6.5, 'abc', 1, 2, True, 6.5, 'abc']
In [10]:
2 in myList
Out[10]:
True
In [11]:
len(myList)
Out[11]:
5

수정 가능성: 리스트

λ¦¬μŠ€νŠΈλŠ” μˆ˜μ •μ΄ κ°€λŠ₯ν•œ μžλ£Œν˜•μ΄λ‹€. μ•„λž˜ μ˜ˆμ œλŠ” 인덱싱을 ν™œμš©ν•˜μ—¬ νŠΉμ • 인덱슀의 값을 λ‹€λ₯Έ κ°’μœΌλ‘œ μˆ˜μ •ν•  수 μžˆμŒμ„ 보여쀀닀. 심지어 μˆ˜μ •λœ ν•­λͺ©μ˜ μžλ£Œν˜•μ΄ λ‹¬λΌμ§ˆ μˆ˜λ„ μžˆλ‹€.

In [12]:
myList[0] = 'Hi'
myList
Out[12]:
['Hi', 2, True, 6.5, 'abc']

리스트 자료형 메서드

μ•„λž˜μ˜ λ©”μ„œλ“œλ“€μ΄ λ¦¬μŠ€νŠΈμ™€ κ΄€λ ¨λœ 기본적인 λ©”μ„œλ“œ 듀이닀. μ•žμ„œ μ„€λͺ…ν•˜μ˜€λ“―이, μ•„λž˜ λ©”μ„œλ“œλ“€μ„ μ‹€ν–‰ν•˜λ©΄ 리슀트 μžμ²΄κ°€ μˆ˜μ •λ  수 μžˆλ‹€.

  • append: 리슀트 끝에 μƒˆλ‘œμš΄ 값을 μΆ”κ°€ν•˜λŠ” 데에 μ‚¬μš©λ¨.
In [13]:
myList.append(False)
print(myList)
['Hi', 2, True, 6.5, 'abc', False]
  • insert: νŠΉμ • 인덱슀의 μœ„μΉ˜μ— ν•­λͺ©μ„ μΆ”κ°€ν•œλ‹€.
In [14]:
myList.insert(2, 4.5)
print(myList)
['Hi', 2, 4.5, True, 6.5, 'abc', False]
  • pop: νŠΉμ • 인덱슀의 μœ„μΉ˜μ— μžˆλŠ” ν•­λͺ©μ„ λ¦¬μŠ€νŠΈμ—μ„œ μ‚­μ œν•œ ν›„ μ‚­μ œλœ κ°’ 리턴. 인자λ₯Ό 받지 μ•ŠμœΌλ©΄ λ§ˆμ§€λ§‰ ν•­λͺ©μ„ λŒ€μƒμœΌλ‘œ ν•œλ‹€.
In [15]:
myList.pop()
Out[15]:
False
In [16]:
myList.pop(2)
Out[16]:
4.5
In [17]:
print(myList)
['Hi', 2, True, 6.5, 'abc']
  • sort: 리슀트 ν•­λͺ©λ“€μ„ 크기 μ˜€λ¦„μ°¨μˆœμœΌλ‘œ μ •λ ¬. reverse μ˜΅μ…˜ λ³€μˆ˜μ˜ 값을 True' μ§€μ •ν•˜λ©΄ λ‚΄λ¦Όμ°¨μˆœ μ •λ ¬. 리턴값은None` μž„μ— μ£Όμ˜ν•  것.

주의: 크기λ₯Ό μ„œλ‘œλΉ„κ΅ν•  수 μžˆλŠ” κ°’λ“€λ§Œ ν•­λͺ©μœΌλ‘œ μ‚¬μš©λœ 경우만 μž‘λ™ν•œλ‹€. 그렇지 μ•ŠμœΌλ©΄ 였λ₯˜κ°€ λ°œμƒν•œλ‹€.

In [18]:
myList.sort()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-18-56aa534bad77> in <module>
----> 1 myList.sort()

TypeError: '<' not supported between instances of 'int' and 'str'
In [19]:
newList = [3.6, 1.7, 8.1, 6.5]
In [20]:
print(f'sort λ©”μ„œλ“œμ˜ 리턴값은 {newList.sort()}μž„.')
print(f'ν•˜μ§€λ§Œ 리슀트 μžμ²΄λŠ” {newList}둜 정렬됨.')
sort λ©”μ„œλ“œμ˜ 리턴값은 Noneμž„.
ν•˜μ§€λ§Œ 리슀트 μžμ²΄λŠ” [1.7, 3.6, 6.5, 8.1]둜 정렬됨.

λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ μ •λ ¬ν•˜κ³ μž ν•  경우 reverseλΌλŠ” ν‚€μ›Œλ“œ 인자λ₯Ό μ‚¬μš©ν•œλ‹€.

In [21]:
newList.sort(reverse=True)
print(newList)
[8.1, 6.5, 3.6, 1.7]
  • reverse λ©”μ„œλ“œλŠ” 리슀트의 μˆœμ„œλ₯Ό λ’€μ§‘λŠ”λ‹€. sort λ©”μ„œλ“œμ™€ λ§ˆμ°¬κ°€μ§€λ‘œ 리턴값은 None이닀.
In [22]:
myList.reverse()
print(myList)
['abc', 6.5, True, 2, 'Hi']
  • del: νŠΉμ • 인덱슀의 값을 μ‚­μ œν•˜λŠ” ν•¨μˆ˜μ΄λ‹€. del μ—„κ²©ν•œ μ˜λ―Έμ—μ„œλŠ” 리슀트 κ΄€λ ¨ λ©”μ„œλ“œκ°€ μ•„λ‹ˆλ‹€. λ‹€λ§Œ popκ³Ό λΉ„μŠ·ν•œ κΈ°λŠ₯을 κ°–κ³  μžˆμ–΄μ„œ μ—¬κΈ°μ„œ μ†Œκ°œν•œλ‹€.
In [23]:
del(myList[2])
myList
Out[23]:
['abc', 6.5, 2, 'Hi']
  • index: νŠΉμ • 값이 λ‚˜νƒ€λ‚˜λŠ” 인덱슀 κ°’ μ€‘μ—μ„œ κ°€μž₯ μž‘μ€ 인덱슀 λ‚΄μ£ΌκΈ°. μ§€μ •λœ 값이 ν•­λͺ©μ΄ μ•„λ‹Œ 경우 였λ₯˜(ValueError) λ°œμƒ.
In [24]:
myList.index(6.5)
Out[24]:
1
In [25]:
myList.index(4.7)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-25-f1ecf4000074> in <module>
----> 1 myList.index(4.7)

ValueError: 4.7 is not in list
  • count: νŠΉμ • 값이 λ¦¬μŠ€νŠΈμ—μ„œ λͺ‡ 번 μ‚¬μš©λ˜μ—ˆλŠ”μ§€ 확인
In [26]:
myList.append(6.5)
print(myList.count(6.5))
2

리스트 해체

리슀트의 길이λ₯Ό μ •ν™•νžˆ μ•Œκ³  μžˆλŠ” 경우 각각의 ν•­λͺ©μ„ λ”°λ‘œλ”°λ‘œ λ–Όμ–΄λ‚΄μ–΄ λ³€μˆ˜μ— μ €μž₯ν•  수 μžˆλ‹€.

In [27]:
x, y, z = [1, 2, 3]
print(f"x = {x}", 
      f"y = {y}",
      f"z = {z}",
      sep='\n')
x = 1
y = 2
z = 3

주의: 리슀트의 길이와 λ³€μˆ˜μ˜ κ°œμˆ˜κ°€ λ‹€λ₯΄λ©΄ 였λ₯˜κ°€ λ°œμƒν•œλ‹€.

In [28]:
x, y = [1, 2, 3]
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-28-43d2015d9ce2> in <module>
----> 1 x, y = [1, 2, 3]

ValueError: too many values to unpack (expected 2)
In [29]:
x, y, z, w = [1, 2, 3]
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-29-6891ae448c90> in <module>
----> 1 x, y, z, w = [1, 2, 3]

ValueError: not enough values to unpack (expected 4, got 3)

리슀트λ₯Ό ν•΄μ²΄ν•˜λ©΄μ„œ μ•žμœΌλ‘œ μ‚¬μš©ν•˜μ§€ μ•Šκ³  버릴 ν•­λͺ©μ€ ꡳ이 이름을 주지 μ•Šμ•„λ„ λœλ‹€. 이λ₯Ό μœ„ν•΄ 밑쀄(underscore, μ–Έλ”μŠ€μ½”μ–΄) 기호λ₯Ό μ‚¬μš©ν•œλ‹€.

In [30]:
x, _, z = [1, 2, 3]
print(f"x = {x}", 
      f"z = {z}",
      sep='\n')
x = 1
z = 3

range 함수

λ¦¬μŠ€νŠΈμ™€ ν•¨κ»˜ 많이 μ‚¬μš©λ˜λŠ” ν•¨μˆ˜μ΄λ‹€. range ν•¨μˆ˜κ°€ μƒμ„±ν•œ 값은 range μžλ£Œν˜•μ΄λ©°, λ¦¬μŠ€νŠΈμ™€ μœ μ‚¬ν•œ κΈ°λŠ₯을 μˆ˜ν–‰ν•œλ‹€.

사용법

range ν•¨μˆ˜λŠ” ν•œ κ°œμ—μ„œ μ΅œλŒ€ μ„Έ 개의 인자λ₯Ό 받을 수 μžˆλ‹€.

  • μΈμžκ°€ ν•œ 개이면 0λΆ€ν„° μΈμžκΉŒμ§€μ˜ ꡬ간을 μ˜λ―Έν•œλ‹€. 단, κ΅¬κ°„μ˜ 끝은 ν¬ν•¨ν•˜μ§€ μ•ŠλŠ”λ‹€.
In [31]:
range(10)
Out[31]:
range(0, 10)

list ν•¨μˆ˜λ₯Ό μ΄μš©ν•˜μ—¬ 0λΆ€ν„° 9κΉŒμ§€μ˜ 숫자둜 이루어진 리슀트λ₯Ό 얻을 수 μžˆλ‹€.

In [32]:
list(range(10))
Out[32]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  • μΈμžκ°€ 두 개이면 κ΅¬κ°„μ˜ 처음과 끝을 λ‚˜νƒ€λ‚Έλ‹€. 단, κ΅¬κ°„μ˜ 끝은 ν¬ν•¨ν•˜μ§€ μ•ŠλŠ”λ‹€.
In [33]:
list(range(5,10))
Out[33]:
[5, 6, 7, 8, 9]
  • μΈμžκ°€ μ„Έ 개이면 λ§ˆμ§€λ§‰ μΈμžλŠ” λͺ‡ κ°œμ”© λ›°μ–΄λ„˜μ„μ§€λ₯Ό μ •ν•˜λŠ” μŠ€ν…μœΌλ‘œ μ‚¬μš©λœλ‹€. 예λ₯Ό λ“€μ–΄, λ§ˆμ§€λ§‰ μΈμžκ°€ 2이면 두 κ°œμ”© κ±΄λ„ˆ λ›°λ©΄μ„œ ꡬ간을 μ •ν•œλ‹€λŠ” μ˜λ―Έμ΄λ‹€.
In [34]:
list(range(3, 10, 2))
Out[34]:
[3, 5, 7, 9]
  • λ§ˆμ§€λ§‰ μΈμžκ°€ 음수이면 μ—­μˆœμœΌλ‘œ ꡬ간을 μ •ν•œλ‹€λŠ” μ˜λ―Έμ΄λ‹€.
In [35]:
list(range(10,1,-1))
Out[35]:
[10, 9, 8, 7, 6, 5, 4, 3, 2]
In [36]:
list(range(10,1,-3))
Out[36]:
[10, 7, 4]

예제

1λΆ€ν„° 10κΉŒμ§€μ˜ μ •μˆ˜λ₯Ό 좜λ ₯ν•˜κ³ μž ν•  λ•Œ μ•„λž˜μ™€ 같이 μ‚¬μš©ν•œλ‹€.

In [37]:
for num in range(1, 11):
    print(num, end=', ')
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 

λΉ„μŠ·ν•œ λ°©μ‹μœΌλ‘œ 1λΆ€ν„° 10κΉŒμ§€μ˜ μ •μˆ˜λ“€μ˜ 리슀트λ₯Ό 생성할 수 μžˆλ‹€.

In [38]:
square_1_to_10 = []

for num in range(1, 11):
    square_1_to_10.append(num**2)
In [39]:
print(square_1_to_10)
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

리스트 활용 예제

리슀트λ₯Ό ν™œμš©ν•˜μ—¬ μ…°μ΅μŠ€ν”Όμ–΄κ°€ μ‚¬μš©ν•œ λ‹¨μ–΄μ˜ 개수λ₯Ό ν™•μΈν•˜κ³ μž ν•œλ‹€.

λ¨Όμ € μ‚¬μ΄νŠΈμ—μ„œ shakespeare.txt νŒŒμΌμ„ λ‹€μš΄λ°›μ•„ μ €μž₯ν•œλ‹€. (μ—¬κΈ°μ„œλŠ” dataλΌλŠ” ν•˜μœ„ 폴더에 μ €μž₯ν•œλ‹€κ³  κ°€μ •ν•œλ‹€.) shakespeare.txt νŒŒμΌμ€ μ…°μ΅μŠ€ν”Όμ–΄μ˜ μž‘ν’ˆμΈ 'ν•œμ—¬λ¦„λ°€μ˜ 꿈'의 λ‚΄μš©μ„ λ‹΄κ³  μžˆλ‹€.

λ¨Όμ € open ν•¨μˆ˜λ₯Ό μ΄μš©ν•˜μ—¬ νŒŒμΌμ„ λΆˆλŸ¬λ“€μΈν›„ λ‚΄μš© 전체λ₯Ό ν•˜λ‚˜μ˜ λ¬Έμžμ—΄λ‘œ textλΌλŠ” λ³€μˆ˜μ— μ €μž₯ν•œλ‹€.

주의: ν…μŠ€νŠΈ νŒŒμΌμ„ μ½μ–΄μ™€μ„œ μ €μž₯ν•˜λŠ” 방식은 데이터셋 닀루기λ₯Ό μ°Έμ‘°ν•œλ‹€.

In [40]:
shakespeare = open("data/shakespeare.txt")
text = shakespeare.read()
shakespeare.close()

주의사항

shakespeare.txt νŒŒμΌμ„ λ‹€μš΄λ‘œλ“œ ν•˜μ§€ μ•Šκ³  직접 확인할 μˆ˜λ„ μžˆλ‹€. 2μž₯μ—μ„œ 닀룬 urllib.request λΌλŠ” λͺ¨λ“ˆμ— ν¬ν•¨λ˜μ–΄ μžˆλŠ” urlopen μ΄λž€ ν•¨μˆ˜λ₯Ό μ΄μš©ν•˜λ©΄ λœλ‹€. λ”°λΌμ„œ μ•„λž˜μ™€ 같이 μ‹€ν–‰ν•˜λ©΄ λœλ‹€.

from urllib.request import urlopen
shakespeare = urlopen("shakespeare.txt")    

이제 textλŠ” λ¬Έμžμ—΄ μžλ£Œν˜•μ΄λ©°, 'ν•œμ—¬λ¦„λ°€μ˜ 꿈' μž‘ν’ˆ λ‚΄μš© 전체λ₯Ό 담은 ν•˜λ‚˜μ˜ λ¬Έμžμ—΄μ΄ ν• λ‹Ήλ˜μ–΄ μžˆλ‹€.

In [41]:
type(text)
Out[41]:
str

text에 ν• λ‹Ήλœ λ¬Έμžμ—΄μ„ print(text) 등을 μ΄μš©ν•˜μ—¬ 확인할 수 μžˆλ‹€. ν•˜μ§€λ§Œ μ—¬κΈ°μ„œλŠ” μ‹€ν–‰ν•˜μ§€ μ•ŠλŠ”λ‹€. ν…μŠ€νŠΈ λ‚΄μš©μ΄ λ„ˆλ¬΄ κΈΈκΈ° λ•Œλ¬Έμ΄λ‹€. 그런데 'ν•œμ—¬λ¦„λ°€μ˜ 꿈'에 μ‚¬μš©λœ λ‹¨μ–΄μ˜ μˆ˜λŠ” λͺ‡ 개일까?

μ‚¬μš©λœ λ‹¨μ–΄μ˜ 수λ₯Ό ν™•μΈν•˜λŠ” 방법 μ€‘μ˜ ν•˜λ‚˜λŠ” text에 ν• λ‹Ήλœ λ¬Έμžμ—΄μ„ 슀페이슀, νƒ­, 쀄바꾸기 등을 κΈ°μ€€μœΌλ‘œ μͺΌκ°œλŠ” 것이닀. λ¬Έμžμ—΄ 클래슀의 split λ©”μ„œλ“œκ°€ 그런 κΈ°λŠ₯을 κ°–κ³  μžˆλ‹€.

In [42]:
text_words = text.split()

len ν•¨μˆ˜λ₯Ό μ΄μš©ν•˜μ—¬ text_words λ¦¬μŠ€νŠΈμ— ν¬ν•¨λœ λ‹¨μ–΄λ“€μ˜ 개수λ₯Ό 확인할 수 μžˆλ‹€.

In [43]:
len(text_words)
Out[43]:
980637

무렀 거의 100만 개의 단어가 ν¬ν•¨λ˜μ–΄ μžˆλ‹€. 그런데 κ³Όμ—° μ…°μ΅μŠ€ν”Όμ–΄κ°€ 100만개의 단어λ₯Ό μ•Œκ³  μžˆμ„κΉŒ? 그럴 μˆ˜κ°€ μ—†λ‹€. μ‹€μ œλ‘œ μ˜μ–΄ 단어가 100λ§Œκ°œκ°€ λ„˜λŠ”λ‹€κ³  μ•Œλ €μ Έ μžˆμ§€λ§Œ ν•œ λͺ…μ˜ μ‚¬λžŒμ΄ 100만개의 단어λ₯Ό ν™œμš©ν•  μˆ˜λŠ” μ—†λ‹€. μ‹€μ œλ‘œ μ…°μ΅μŠ€ν”Όμ–΄λŠ” μžμ‹ μ˜ μž‘ν’ˆ 전체λ₯Ό 톡틀어 28,829개의 단어λ₯Ό μ‚¬μš©ν–ˆλ‹€κ³  μ•Œλ €μ Έ μžˆλ‹€.

자료 근거: https://www.opensourceshakespeare.org/stats/

κ·Έλ ‡λ‹€λ©΄ 100만과 2만9천 μ‚¬μ΄μ˜ μ˜€μ°¨λŠ” μ–΄λ–»κ²Œ λ°œμƒν•˜μ˜€μ„κΉŒ?

중복 단어 제거

λ¨Όμ € λ¦¬μŠ€νŠΈμ—λŠ” ν•­λͺ©μ΄ μ—¬λŸ¬ 번 μ€‘λ³΅ν•΄μ„œ μ‚¬μš©λ  수 μžˆλ‹€. λ”°λΌμ„œ μ€‘λ³΅λœ ν•­λͺ©λ“€μ„ μ œκ±°ν•΄μ•Όλ§Œ μ‹€μ œλ‘œ μ‚¬μš©λœ μ„œλ‘œ λ‹€λ₯Έ λ‹¨μ–΄λ“€μ˜ 개수λ₯Ό 확인할 수 μžˆμ„ 것이닀.

μ—¬κΈ°μ„œλŠ” 집합 μžλ£Œν˜•μ„ ν™œμš©ν•˜μ—¬ 쀑볡을 μ œκ±°ν•˜λŠ” 방법을 μ†Œκ°œν•œλ‹€.

주의사항

  • 집합 μžλ£Œν˜•μ€ μ€‘ν•™κ΅μ—μ„œ 배운 집합 κ°œλ…μ„ μ‚¬μš©ν•˜λ©°, λ™μΌν•œ μ›μ†Œκ°€ 두 번 μ‚¬μš©λ˜μ–΄λ„ ν•œ 번 μ‚¬μš©ν•œ κ²ƒμœΌλ‘œ κ°„μ£Όν•œλ‹€.
  • 집합 μžλ£Œν˜•μ„ ν™œμš©ν•˜λŠ” λ‹€μ–‘ν•­ 방식이 μ‘΄μž¬ν•˜μ§€λ§Œ μ—¬κΈ°μ„œλŠ” 리슀트 μžλ£Œν˜•μ„ 집합 μžλ£Œν˜•μœΌλ‘œ ν˜•λ³€ν™˜μ‹œμΌœμ„œ μ€‘λ³΅λœ ν•­λͺ©μ„ μ œκ±°ν•˜λŠ” μš©λ„λ‘œλ§Œ μ‚¬μš©ν•œλ‹€.
  • 집합 μžλ£Œν˜•μœΌλ‘œμ˜ ν˜•λ³€ν™˜μ€ setμ΄λž€ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λ©΄ λœλ‹€.
In [44]:
words_set = set(text_words)

이제 len ν•¨μˆ˜λ₯Ό μ΄μš©ν•˜μ—¬ words_set μ§‘ν•©μ˜ μ›μ†Œμ˜ 개수λ₯Ό μ•Œμ•„λ‚Ό 수 μžˆλ‹€.

In [45]:
len(words_set)
Out[45]:
33505

이제, μ„œλ‘œ λ‹€λ₯Έ λ‹¨μ–΄μ˜ κ°œμˆ˜κ°€ 33,505κ°œμž„μ„ 확인할 수 μžˆλ‹€. ν•˜μ§€λ§Œ μ—¬μ „νžˆ 2만 9μ²œμ—¬κ°œ λ³΄λ‹€λŠ” 많이 크닀.

무엇이 문제일까?

기호 제외하기

첫 40개 단어λ₯Ό μ•„λž˜μ™€ 같이 ν™•μΈν•˜λ©΄ 단어 이외에 μ‰Όν‘œ, λŠλ‚Œν‘œ, 콜둠 등이 λ¦¬μŠ€νŠΈμ— ν¬ν•¨λ˜μ–΄ μžˆμŒμ„ μ•Œ 수 μžˆλ‹€.

In [46]:
text_words[:30]
Out[46]:
['A',
 "MIDSUMMER-NIGHT'S",
 'DREAM',
 'Now',
 ',',
 'fair',
 'Hippolyta',
 ',',
 'our',
 'nuptial',
 'hour',
 'Draws',
 'on',
 'apace',
 ':',
 'four',
 'happy',
 'days',
 'bring',
 'in',
 'Another',
 'moon',
 ';',
 'but',
 'O',
 '!',
 'methinks',
 'how',
 'slow',
 'This']

λ”°λΌμ„œ μ‰Όν‘œ(,), λ§ˆμΉ¨ν‘œ(.), λŠλ‚Œν‘œ(!), λ¬ΌμŒν‘œ(?), 콜둠(:), μ„Έλ―Έμ½œλ‘ (;) 등을 λ¦¬μŠ€νŠΈμ—μ„œ μ œκ±°ν•΄μ•Ό ν•œλ‹€.

그리고 κ²½μš°μ— 따라 단어 끝에 μ‰Όν‘œ, λŠλ‚Œν‘œ 등이 λΆ™μ–΄ μžˆμ„ μˆ˜λ„ μžˆλŠ”λ°, λ™μΌν•œ 단어에 그런 κΈ°ν˜Έκ°€ λΆ™λŠ” κ²½μš°μ™€ 그렇지 μ•Šμ€ κ²½μš°λ„ μ€‘λ³΅μœΌλ‘œ μ²˜λ¦¬ν•΄μ•Ό ν•œλ‹€.

그런데 μ–΄λ–»κ²Œ ν• κΉŒ? 그리고 μ–΄λ–»κ²Œ μ–΄λ–€ κΈ°ν˜Έλ“€μ΄ μ‚¬μš©λ˜μ—ˆλŠ”μ§€ μ•Œμ•„λ‚Ό 수 μžˆμ„κΉŒ?

μ™„λ²½ν•˜μ§€λŠ” μ•Šκ² μ§€λ§Œ μ•„λž˜μ™€ 같이 ν•˜λ‚˜μ˜ 기호둜 κ΅¬μ„±λœ λ¬Έμžμ—΄μ€ 길이가 1μ΄λΌλŠ” 사싀을 μ΄μš©ν•˜μ—¬ μ‚¬μš©λœ κΈ°ν˜Έλ“€λ§Œ λ”°λ‘œ ν•˜λ‚˜μ˜ 리슀트둜 λ§Œλ“€μ–΄λ³΄λ©΄ μ‚¬μš©λœ 기호λ₯Ό 거의 μ•Œμ•„λ‚Ό 수 μžˆμ„ 것이닀.

In [47]:
word_of_length_1 = []

for word in text_words:
    if len(word) == 1:
        word_of_length_1.append(word)

그런데 word_of_length_1 리슀트의 길이가 맀우 크닀.

In [48]:
len(word_of_length_1)
Out[48]:
203281

ν•˜μ§€λ§Œ μ—­μ‹œ 쀑볡이 λ§Žμ„ κ²ƒμ΄λ―€λ‘œ μ§‘ν•©μœΌλ‘œ ν˜•λ³€ν™˜ν•˜μ—¬ ν™•μΈν•˜λ©΄ κ°œμˆ˜κ°€ ν™• 쀄어든닀.

In [49]:
len(set(word_of_length_1))
Out[49]:
39

39개 뿐이라 직접 확인할 수 μžˆλ‹€.

In [50]:
print(set(word_of_length_1))
{'C', 'D', 'N', 'H', 'O', 'I', 'A', ':', 'T', 'b', 's', '.', 'h', 'd', 'a', '!', 'u', 'c', '2', ',', '[', 'M', 'v', 't', 'o', 'V', 'G', 'y', ';', 'i', '?', 'l', 'B', 'e', 'R', ']', 'r', 'j', 'p'}

μœ„μ—μ„œ ν™•μΈν•œ κ²°κ³Ό μ‚¬μš©λœ κΈ°ν˜ΈλŠ” ",.!?:;[]" λ¬Έμžμ—΄μ— ν¬ν•¨λœ 8개의 κΈ°ν˜Έμž„μ„ μ•Œ 수 μžˆλ‹€. 이제 text_wordsμ—μ„œ μœ„ κΈ°ν˜Έλ“€μ„ μ œκ±°ν•˜λ©΄ 되며, 이λ₯Ό μœ„ν•΄ λ¬Έμžμ—΄μ˜ strip λ©”μ„œλ“œλ₯Ό ν™œμš©ν•œλ‹€.

In [51]:
# μ œκ±°ν•œ λ¬Έμžλ“€
symbols = r" \n\t,.!?:;[]"

# 기호λ₯Ό μ œκ±°ν•œ 단어λ₯Ό μ €μž₯ν•  λ³€μˆ˜
text_words_stripped = []

# text_words에 ν¬ν•¨λœ λ‹¨μ–΄λ“€μ—μ„œ 기호λ₯Ό μ œκ±°ν•œ ν›„ λΉˆλ¬Έμžμ—΄μ΄ μ•„λ‹Œ κ²ƒλ§Œ μΆ”κ°€
for word in text_words:
    word_stripped = word.strip(symbols)
    if len(word_stripped) > 0:
        text_words_stripped.append(word_stripped)

리슀트의 κΈΈμ΄λŠ”?

In [52]:
len(text_words_stripped)
Out[52]:
813736

μ€‘λ³΅λ˜μ§€ μ•ŠλŠ” λ‹¨μ–΄μ˜ κ°œμˆ˜λŠ”?

In [53]:
len(set(text_words_stripped))
Out[53]:
32308

μ—¬μ „νžˆ μ’€ λ§Žλ‹€.

μ΄λ²ˆμ—” λŒ€λ¬Έμžμ™€ μ†Œλ¬Έμžλ₯Ό κ΅¬λΆ„ν•˜μ§€ μ•Šκ³  λ‹¨μ–΄μ˜ 동일성 μ—¬λΆ€λ₯Ό λ”°μ Έ 보자.

In [54]:
# μ œκ±°ν•œ λ¬Έμžλ“€
symbols = r" \n\t,.!?:;[]"

# 기호λ₯Ό μ œκ±°ν•œ 단어λ₯Ό μ €μž₯ν•  λ³€μˆ˜
text_words_stripped = []

# text_words에 ν¬ν•¨λœ λ‹¨μ–΄λ“€μ—μ„œ 기호λ₯Ό μ œκ±°ν•œ ν›„ λΉˆλ¬Έμžμ—΄μ΄ μ•„λ‹Œ κ²ƒλ§Œ μΆ”κ°€
# 단, λͺ¨λ‘ μ†Œλ¬Έμžν™” ν•΄μ„œ μΆ”κ°€
for word in text_words:
    word_stripped = word.strip(symbols)
    if len(word_stripped) > 0:
        text_words_stripped.append(word_stripped.lower())

μ€‘λ³΅λ˜μ§€ μ•Šμ€ λ‹¨μ–΄μ˜ κ°œμˆ˜λŠ”?

In [55]:
len(set(text_words_stripped))
Out[55]:
28094

이제 (거의) μ œλŒ€λ‘œ 된 κ²°κ³Όλ₯Ό μ–»κ²Œ λ˜μ—ˆλ‹€.

연습문제

  1. μ•„λž˜ 기쀀을 λ§Œμ‘±ν•˜λŠ” nested_sum ν•¨μˆ˜λ₯Ό κ΅¬ν˜„ν•˜λΌ.

    • 리슀트λ₯Ό 인자둜 μ‚¬μš©ν•œλ‹€.
    • 리슀트의 ν•­λͺ©μ€ μ •μˆ˜λ“€μ˜ λ¦¬μŠ€νŠΈκ°€ μ‚¬μš©λœλ‹€.
    • 리턴값은 λ¦¬μŠ€νŠΈμ— μ‚¬μš©λœ λͺ¨λ“  μ •μˆ˜λ“€μ˜ ν•©λ‹ˆλ‹€.

      예제:

      >>> t = [[1, 2], [3], [4, 5, 6]]
      >>> nested_sum(t)
      21
      

      힌트: sum ν•¨μˆ˜ ν™œμš©

  2. μ•„λž˜ 기쀀을 λ§Œμ‘±ν•˜λŠ” cumsum ν•¨μˆ˜λ₯Ό κ΅¬ν˜„ν•˜λΌ.

    • μ •μˆ˜λ“€μ˜ 리슀트λ₯Ό 인자둜 μ‚¬μš©ν•œλ‹€.
    • 리턴값은 λ¦¬μŠ€νŠΈμ— μ‚¬μš©λœ μ •μˆ˜λ“€μ„ ν•˜λ‚˜μ”© λˆ„μ ν•΄μ„œ ν•©ν•œ κ°’λ“€μ˜ λ¦¬μŠ€νŠΈμ΄λ‹€.

      예제:

      >>> t = [1, 2, 3]
      >>> cumsum(t)
      [1, 3, 6]
      

      힌트: append λ©”μ„œλ“œ ν™œμš©

  3. μ•„λž˜ 기쀀을 λ§Œμ‘±ν•˜λŠ” middle ν•¨μˆ˜λ₯Ό κ΅¬ν˜„ν•˜λΌ.

    • μ •μˆ˜λ“€μ˜ 리슀트λ₯Ό 인자둜 μ‚¬μš©ν•œλ‹€.
    • 리턴값은 리슀트의 처음과 끝에 μ‚¬μš©λœ ν•­λͺ©μ„ μ œκ±°ν•œ λ¦¬μŠ€νŠΈμ΄λ‹€.

      예제:

      >>> t = [1, 2, 3, 4]
      >>> middle(t)
      [2, 3]
      

      힌트: μŠ¬λΌμ΄μ‹± ν™œμš©

  4. μ•„λž˜ 기쀀을 λ§Œμ‘±ν•˜λŠ” chop ν•¨μˆ˜λ₯Ό κ΅¬ν˜„ν•˜λΌ.

    • μ •μˆ˜λ“€μ˜ 리슀트λ₯Ό 인자둜 μ‚¬μš©ν•œλ‹€.
    • 리슀트의 처음과 끝에 μ‚¬μš©λœ ν•­λͺ©μ„ μ œκ±°ν•œλ‹€.
    • 리턴값은 None이닀.

      예제:

      >>> t = [1, 2, 3, 4]
      >>> chop(t)
      >>> t
      [2, 3]
      

      힌트: del ν•¨μˆ˜ ν™œμš©

  5. μ•„λž˜ 기쀀을 λ§Œμ‘±ν•˜λŠ” is_sorted ν•¨μˆ˜λ₯Ό κ΅¬ν˜„ν•˜λΌ.

    • 리슀트λ₯Ό 인자둜 μ‚¬μš©ν•œλ‹€.
    • μž…λ ₯된 λ¦¬μŠ€νŠΈκ°€ 올림차순으둜 정렬이 λ˜μ–΄ 있으면 Trueλ₯Ό κ·Έλ ‡μΉ˜ μ•ŠμœΌλ©΄ Falseλ₯Ό λ¦¬ν„΄ν•œλ‹€.

      예제:

      >>> is_sorted([1, 2, 2])
      True
      >>> is_sorted(['b', 'a'])
      False
      

      힌트: sort λ©”μ„œλ“œ λ˜λŠ” sorted ν•¨μˆ˜ ν™œμš©

  6. μ•„λž˜ 기쀀을 λ§Œμ‘±ν•˜λŠ” is_anagram ν•¨μˆ˜λ₯Ό κ΅¬ν˜„ν•˜λΌ.

    • 두 개의 λ¬Έμžμ—΄μ„ μž…λ ₯λ°›λŠ”λ‹€.
    • 두 λ¬Έμžμ—΄μ΄ μ„œλ‘œ μ• λ„ˆκ·Έλž¨μ˜ 관계이면 Trueλ₯Ό 그렇지 μ•ŠμœΌλ©΄ Falseλ₯Ό λ¦¬ν„΄ν•œλ‹€.

      주의: μ• λ„ˆκ·Έλž¨μ˜ κ΄€κ³„λŠ” λ™μΌν•œ 문자λ₯Ό λ™μΌν•œ 개수만큼 μ‚¬μš©ν•œ 관계이닀.
      예제:

      >>> is_anagram('hello', 'eollh')
      True
      >>> is_anagram('hello', 'eoLLh')
      False
      
  7. continue, break, pass μ„Έ κ³„μ˜ νŠΉλ³„ν•œ λͺ…λ Ήλ¬Έμ˜ 이해λ₯Ό λ„μ™€μ£ΌλŠ” λ¬Έμ œμ΄λ‹€.

    1. μ•„λž˜ for λ°˜λ³΅λ¬Έμ„ μ™„μ„±ν•˜λΌ.
      for n in range(2,10):
           for x in range(2, n):
               # μ½”λ“œλ₯Ό μ™„μ„±ν•˜μ„Έμš”
               pass
           else:
               # μ½”λ“œλ₯Ό μ™„μ„±ν•˜μ„Έμš”.
               pass
      
      μ‹€ν–‰κ²°κ³ΌλŠ” λ‹€μŒκ³Ό κ°™μ•„μ•Ό ν•œλ‹€.
       2은 μ†Œμˆ˜λ‹€.
       3은 μ†Œμˆ˜λ‹€.
       4 = 2*2
       5은 μ†Œμˆ˜λ‹€.
       6 = 2*3
       7은 μ†Œμˆ˜λ‹€.
       8 = 2*4
       9 = 3*3
      힌트:
       * `for` 반볡문과 ν•¨κ»˜ μ‚¬μš©λ˜λŠ” `else`의 역할에 μ£Όλͺ©ν•  것.
       * `break` ν™œμš©
    2. μ•„λž˜ for λ°˜λ³΅λ¬Έμ„ μ™„μ„±ν•˜λΌ.
      for n in range(2,10):
           # μ½”λ“œλ₯Ό μ™„μ„±ν•˜μ„Έμš”
           pass
      
      μ‹€ν–‰κ²°κ³ΌλŠ” λ‹€μŒκ³Ό κ°™μ•„μ•Ό ν•œλ‹€.
       짝수 2을(λ₯Ό) μ°Ύμ•˜λ‹€.
       3을 μ°Ύμ•˜λ‹€.
       짝수 4을(λ₯Ό) μ°Ύμ•˜λ‹€.
       5을 μ°Ύμ•˜λ‹€.
       짝수 6을(λ₯Ό) μ°Ύμ•˜λ‹€.
       7을 μ°Ύμ•˜λ‹€.
       짝수 8을(λ₯Ό) μ°Ύμ•˜λ‹€.
       9을 μ°Ύμ•˜λ‹€.
      힌트:
       * `if` 쑰건문과 `continue` λͺ…λ Ήλ¬Έ ν™œμš©
    3. μ•„λž˜ for λ°˜λ³΅λ¬Έμ„ μ™„μ„±ν•˜λΌ.
      for n in range(2,10):
           # μ½”λ“œλ₯Ό μ™„μ„±ν•˜μ„Έμš”
           pass
      
      μ‹€ν–‰κ²°κ³ΌλŠ” λ‹€μŒκ³Ό κ°™μ•„μ•Ό ν•œλ‹€.
       짝수 2을(λ₯Ό) μ°Ύμ•˜λ‹€.
       2을 μ°Ύμ•˜λ‹€.
       3을 μ°Ύμ•˜λ‹€.
       짝수 4을(λ₯Ό) μ°Ύμ•˜λ‹€.
       4을 μ°Ύμ•˜λ‹€.
       5을 μ°Ύμ•˜λ‹€.
       짝수 6을(λ₯Ό) μ°Ύμ•˜λ‹€.
       6을 μ°Ύμ•˜λ‹€.
       7을 μ°Ύμ•˜λ‹€.
       짝수 8을(λ₯Ό) μ°Ύμ•˜λ‹€.
       8을 μ°Ύμ•˜λ‹€.
       9을 μ°Ύμ•˜λ‹€.
      힌트:
       * `if` 쑰건문과 `pass` λͺ…λ Ήλ¬Έ ν™œμš©