데이터 유형 및 데이터 구조

Beginner

This tutorial is from open-source community. Access the source code

소개

이 섹션에서는 튜플 (tuple) 과 딕셔너리 (dictionary) 형태의 데이터 구조를 소개합니다.

이것은 가이드 실험입니다. 학습과 실습을 돕기 위한 단계별 지침을 제공합니다.각 단계를 완료하고 실무 경험을 쌓기 위해 지침을 주의 깊게 따르세요. 과거 데이터에 따르면, 이것은 초급 레벨의 실험이며 완료율은 93%입니다.학습자들로부터 100%의 긍정적인 리뷰율을 받았습니다.

기본 데이터 타입 (Primitive Datatypes)

Python 은 몇 가지 기본 데이터 타입 (primitive types) 을 가지고 있습니다:

  • 정수 (Integers)
  • 부동 소수점 숫자 (Floating point numbers)
  • 문자열 (Strings) (텍스트)

우리는 소개에서 이것들에 대해 배웠습니다.

None 타입

email_address = None

None은 종종 선택적 값이나 누락된 값을 위한 자리 표시자로 사용됩니다. 조건문에서 False로 평가됩니다.

if email_address:
    send_email(email_address, msg)

데이터 구조 (Data Structures)

실제 프로그램은 더 복잡한 데이터를 가집니다. 예를 들어, 주식 보유에 대한 정보:

100 shares of GOOG at $490.10

이것은 세 부분으로 구성된 "객체 (object)"입니다:

  • 주식의 이름 또는 기호 ("GOOG", 문자열)
  • 주식 수 (100, 정수)
  • 가격 (490.10, 부동 소수점 숫자)

튜플 (Tuples)

튜플은 함께 그룹화된 값들의 모음입니다.

예시:

s = ('GOOG', 100, 490.1)

때로는 구문에서 ()가 생략됩니다.

s = 'GOOG', 100, 490.1

특수한 경우 (0-튜플, 1-튜플).

t = ()            ## 빈 튜플
w = ('GOOG', )    ## 1-항목 튜플

튜플은 종종 단순한 레코드 또는 구조를 나타내는 데 사용됩니다. 일반적으로 여러 부분으로 구성된 단일 *객체 (object)*입니다. 좋은 비유는 다음과 같습니다: 튜플은 데이터베이스 테이블의 단일 행과 같습니다.

튜플 내용은 정렬됩니다 (배열과 유사).

s = ('GOOG', 100, 490.1)
name = s[0]                 ## 'GOOG'
shares = s[1]               ## 100
price = s[2]                ## 490.1

하지만 내용은 수정할 수 없습니다.

>>> s[1] = 75
TypeError: object does not support item assignment

하지만 현재 튜플을 기반으로 새로운 튜플을 만들 수 있습니다.

s = (s[0], 75, s[2])

튜플 패킹 (Tuple Packing)

튜플은 관련 항목들을 단일 *개체 (entity)*로 함께 묶는 데 더 중점을 둡니다.

s = ('GOOG', 100, 490.1)

그런 다음 튜플은 단일 객체로 프로그램의 다른 부분으로 쉽게 전달될 수 있습니다.

튜플 언패킹 (Tuple Unpacking)

튜플을 다른 곳에서 사용하려면, 튜플의 부분을 변수로 언패킹 (unpacking) 할 수 있습니다.

name, shares, price = s
print('Cost', shares * price)

왼쪽에 있는 변수의 수는 튜플 구조와 일치해야 합니다.

name, shares = s     ## ERROR
Traceback (most recent call last):
...
ValueError: too many values to unpack

튜플 vs. 리스트 (Tuples vs. Lists)

튜플은 읽기 전용 리스트처럼 보입니다. 하지만 튜플은 여러 부분으로 구성된 단일 항목에 가장 자주 사용됩니다. 리스트는 일반적으로 서로 다른 항목들의 모음이며, 일반적으로 모두 동일한 유형입니다.

record = ('GOOG', 100, 490.1)       ## 포트폴리오의 레코드를 나타내는 튜플

symbols = [ 'GOOG', 'AAPL', 'IBM' ]  ## 세 개의 주식 기호를 나타내는 리스트

딕셔너리 (Dictionaries)

딕셔너리는 키 (key) 를 값 (value) 에 매핑하는 것입니다. 때로는 해시 테이블 (hash table) 또는 연관 배열 (associative array) 이라고도 합니다. 키는 값에 접근하기 위한 인덱스 역할을 합니다.

s = {
    'name': 'GOOG',
    'shares': 100,
    'price': 490.1
}

일반적인 연산 (Common operations)

딕셔너리에서 값을 가져오려면 키 이름을 사용하십시오.

>>> print(s['name'], s['shares'])
GOOG 100
>>> s['price']
490.10
>>>

값을 추가하거나 수정하려면 키 이름을 사용하여 할당하십시오.

>>> s['shares'] = 75
>>> s['date'] = '6/6/2007'
>>>

값을 삭제하려면 del 문을 사용하십시오.

>>> del s['date']
>>>

딕셔너리가 필요한 이유 (Why dictionaries?)

딕셔너리는 많은 서로 다른 값이 있고 해당 값을 수정하거나 조작해야 할 때 유용합니다. 딕셔너리는 코드를 더 읽기 쉽게 만듭니다.

s['price']
## vs
s[2]

지난 몇 개의 연습에서, 데이터 파일 portfolio.csv를 읽는 프로그램을 작성했습니다. csv 모듈을 사용하면 파일을 행별로 쉽게 읽을 수 있습니다.

>>> import csv
>>> f = open('portfolio.csv')
>>> rows = csv.reader(f)
>>> next(rows)
['name', 'shares', 'price']
>>> row = next(rows)
>>> row
['AA', '100', '32.20']
>>>

파일을 읽는 것은 쉽지만, 종종 데이터를 읽는 것 이상을 수행하고 싶을 것입니다. 예를 들어, 데이터를 저장하고 일부 계산을 수행하기 시작할 수 있습니다. 불행히도, 원시 "행" 데이터는 작업할 수 있는 충분한 정보를 제공하지 않습니다. 예를 들어, 간단한 수학 계산조차 작동하지 않습니다.

>>> row = ['AA', '100', '32.20']
>>> cost = row[1] * row[2]
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
TypeError: can't multiply sequence by non-int of type 'str'
>>>

더 많은 작업을 수행하려면 일반적으로 원시 데이터를 어떤 방식으로 해석하고 나중에 작업할 수 있도록 더 유용한 종류의 객체로 변환해야 합니다. 두 가지 간단한 옵션은 튜플 (tuples) 또는 딕셔너리 (dictionaries) 입니다.

연습 문제 2.1: 튜플 (Tuples)

대화형 프롬프트에서 위의 행을 나타내는 다음 튜플을 생성하되, 숫자 열을 적절한 숫자로 변환합니다.

>>> t = (row[0], int(row[1]), float(row[2]))
>>> t
('AA', 100, 32.2)
>>>

이를 사용하여 주식 수와 가격을 곱하여 총 비용을 계산할 수 있습니다.

>>> cost = t[1] * t[2]
>>> cost
3220.0000000000005
>>>

파이썬에서 수학이 깨졌나요? 3220.0000000000005 라는 답은 무엇인가요?

이것은 컴퓨터의 부동 소수점 하드웨어가 Base-10 이 아닌 Base-2 에서만 소수를 정확하게 표현할 수 있다는 아티팩트입니다. Base-10 소수를 포함하는 간단한 계산조차도 작은 오류가 발생합니다. 이것은 일반적이지만, 이전에 본 적이 없다면 다소 놀라울 수 있습니다.

이것은 부동 소수점 소수를 사용하는 모든 프로그래밍 언어에서 발생하지만, 인쇄할 때 종종 숨겨집니다. 예를 들어:

>>> print(f'{cost:0.2f}')
3220.00
>>>

튜플은 읽기 전용입니다. 주식 수를 75 로 변경하여 이를 확인하십시오.

>>> t[1] = 75
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>>

튜플 내용을 변경할 수 없지만, 항상 이전 튜플을 대체하는 완전히 새로운 튜플을 만들 수 있습니다.

>>> t = (t[0], 75, t[2])
>>> t
('AA', 75, 32.2)
>>>

이처럼 기존 변수 이름을 다시 할당할 때마다 이전 값은 버려집니다. 위의 할당이 튜플을 수정하는 것처럼 보일 수 있지만, 실제로는 새로운 튜플을 생성하고 이전 튜플을 버리는 것입니다.

튜플은 종종 값을 변수로 묶고 풀 때 사용됩니다. 다음을 시도해 보십시오.

>>> name, shares, price = t
>>> name
'AA'
>>> shares
75
>>> price
32.2
>>>

위의 변수를 가져와 다시 튜플로 묶습니다.

>>> t = (name, 2*shares, price)
>>> t
('AA', 150, 32.2)
>>>

연습 문제 2.2: 데이터 구조로서의 딕셔너리 (Dictionaries)

튜플의 대안은 대신 딕셔너리를 만드는 것입니다.

>>> d = {
        'name' : row[0],
        'shares' : int(row[1]),
        'price'  : float(row[2])
    }
>>> d
{'name': 'AA', 'shares': 100, 'price': 32.2 }
>>>

이 보유 자산의 총 비용을 계산합니다.

>>> cost = d['shares'] * d['price']
>>> cost
3220.0000000000005
>>>

위의 튜플을 포함하는 동일한 계산과 이 예제를 비교합니다. 주식 수를 75 로 변경합니다.

>>> d['shares'] = 75
>>> d
{'name': 'AA', 'shares': 75, 'price': 32.2 }
>>>

튜플과 달리 딕셔너리는 자유롭게 수정할 수 있습니다. 몇 가지 속성을 추가합니다.

>>> d['date'] = (6, 11, 2007)
>>> d['account'] = 12345
>>> d
{'name': 'AA', 'shares': 75, 'price':32.2, 'date': (6, 11, 2007), 'account': 12345}
>>>

연습 문제 2.3: 몇 가지 추가적인 딕셔너리 연산

딕셔너리를 리스트로 변환하면 모든 키를 얻을 수 있습니다.

>>> list(d)
['name', 'shares', 'price', 'date', 'account']
>>>

마찬가지로, for 문을 사용하여 딕셔너리를 반복하면 키를 얻게 됩니다.

>>> for k in d:
        print('k =', k)

k = name
k = shares
k = price
k = date
k = account
>>>

동시에 조회를 수행하는 이 변형을 시도해 보십시오.

>>> for k in d:
        print(k, '=', d[k])

name = AA
shares = 75
price = 32.2
date = (6, 11, 2007)
account = 12345
>>>

keys() 메서드를 사용하여 모든 키를 얻을 수도 있습니다.

>>> keys = d.keys()
>>> keys
dict_keys(['name', 'shares', 'price', 'date', 'account'])
>>>

keys()는 특별한 dict_keys 객체를 반환한다는 점에서 약간 특이합니다.

이것은 원래 딕셔너리에 대한 오버레이로, 딕셔너리가 변경되더라도 항상 현재 키를 제공합니다. 예를 들어, 다음을 시도해 보십시오.

>>> del d['account']
>>> keys
dict_keys(['name', 'shares', 'price', 'date'])
>>>

d.keys()를 다시 호출하지 않았음에도 불구하고 keys에서 'account'가 사라졌다는 점에 주의하십시오.

키와 값을 함께 사용하는 더 우아한 방법은 items() 메서드를 사용하는 것입니다. 이 메서드는 (key, value) 튜플을 제공합니다.

>>> items = d.items()
>>> items
dict_items([('name', 'AA'), ('shares', 75), ('price', 32.2), ('date', (6, 11, 2007))])
>>> for k, v in d.items():
        print(k, '=', v)

name = AA
shares = 75
price = 32.2
date = (6, 11, 2007)
>>>

items와 같은 튜플이 있는 경우 dict() 함수를 사용하여 딕셔너리를 만들 수 있습니다. 시도해 보십시오.

>>> items
dict_items([('name', 'AA'), ('shares', 75), ('price', 32.2), ('date', (6, 11, 2007))])
>>> d = dict(items)
>>> d
{'name': 'AA', 'shares': 75, 'price':32.2, 'date': (6, 11, 2007)}
>>>

요약

축하합니다! 데이터 유형 및 데이터 구조 랩을 완료했습니다. LabEx 에서 더 많은 랩을 연습하여 기술을 향상시킬 수 있습니다.