Python3 데이터 구조


이 장에서는 앞서 배운 지식 포인트를 바탕으로 Python 데이터 구조를 주로 소개합니다.


List

Python의 목록은 변경 가능합니다. 이는 목록을 문자열 및 튜플과 구별하는 가장 중요한 기능입니다. 한 문장에서 목록은 수정할 수 있지만 문자열과 튜플은 수정할 수 없습니다.

다음은 Python에서 목록을 작성하는 방법입니다:

方法描述
list.append(x)把一个元素添加到列表的结尾,相当于 a[len(a):] = [x]。
list.extend(L)通过添加指定列表的所有元素来扩充列表,相当于 a[len(a):] = L。
list.insert(i, x)在指定位置插入一个元素。第一个参数是准备插入到其前面的那个元素的索引,例如 a.insert(0, x) 会插入到整个列表之前,而 a.insert(len(a), x) 相当于 a.append(x) 。
list.remove(x)删除列表中值为 x 的第一个元素。如果没有这样的元素,就会返回一个错误。
list.pop([i])从列表的指定位置删除元素,并将其返回。如果没有指定索引,a.pop()返回最后一个元素。元素随即从列表中被删除。(方法中 i 两边的方括号表示这个参数是可选的,而不是要求你输入一对方括号,你会经常在 Python 库参考手册中遇到这样的标记。)
list.clear()移除列表中的所有项,等于del a[:]。
list.index(x)返回列表中第一个值为 x 的元素的索引。如果没有匹配的元素就会返回一个错误。
list.count(x)返回 x 在列表中出现的次数。
list.sort()对列表中的元素进行排序。
list.reverse()倒排列表中的元素。
list.copy()返回列表的浅复制,等于a[:]。

다음 예는 목록의 메소드 대부분을 보여줍니다.

>>> a = [66.25, 333, 333, 1, 1234.5]
>>> print(a.count(333), a.count(66.25), a.count('x'))
2 1 0
>>> a.insert(2, -1)
>>> a.append(333)
>>> a
[66.25, 333, -1, 333, 1, 1234.5, 333]
>>> a.index(333)
1
>>> a.remove(333)
>>> a
[66.25, -1, 333, 1, 1234.5, 333]
>>> a.reverse()
>>> a
[333, 1234.5, 1, 333, -1, 66.25]
>>> a.sort()
>>> a
[-1, 1, 66.25, 333, 333, 1234.5]

참고: 삽입, 제거 또는 정렬과 같이 목록을 수정하는 메소드에는 반환 값이 없습니다.


리스트를 스택으로 사용하기

리스트 방식을 사용하면 리스트를 스택으로 쉽게 사용할 수 있습니다. 스택은 특정 데이터 구조이며, 처음 입력한 요소가 마지막에 해제됩니다(후입선출). ). 스택의 맨 위에 요소를 추가하려면 add() 메서드를 사용하세요. 인덱스를 지정하지 않고 pop() 메서드를 사용하여 스택 상단에서 요소를 해제할 수 있습니다. 예:

>>> stack = [3, 4, 5]
>>> stack.append(6)
>>> stack.append(7)
>>> stack
[3, 4, 5, 6, 7]
>>> stack.pop()
7
>>> stack
[3, 4, 5, 6]
>>> stack.pop()
6
>>> stack.pop()
5
>>> stack
[3, 4]

목록을 대기열로 사용

목록을 대기열로 사용할 수도 있지만 대기열에 추가된 첫 번째 요소가 가장 먼저 제거됩니다. 그런 목적으로 목록을 작성합니다. 목록 끝에서 요소를 추가하거나 팝하는 것은 빠르지만, 목록의 선두에서 요소를 삽입하거나 팝하는 것은 빠르지 않습니다(다른 모든 요소는 하나씩 이동해야 하기 때문입니다).

>>> from collections import deque
>>> queue = deque(["Eric", "John", "Michael"])
>>> queue.append("Terry")           # Terry arrives
>>> queue.append("Graham")          # Graham arrives
>>> queue.popleft()                 # The first to arrive now leaves
'Eric'
>>> queue.popleft()                 # The second to arrive now leaves
'John'
>>> queue                           # Remaining queue in order of arrival
deque(['Michael', 'Terry', 'Graham'])

List comprehensions

List comprehensions은 시퀀스에서 목록을 만드는 간단한 방법을 제공합니다. 일반적으로 애플리케이션은 시퀀스의 각 요소에 일부 작업을 적용하고 그 결과를 요소로 사용하여 새 목록을 생성하거나 특정 기준에 따라 하위 시퀀스를 만듭니다.

모든 목록 이해에는 for 뒤에 표현식이 있고 0개 이상의 for 또는 if 절이 있습니다. 반환 결과는 표현식을 기반으로 하는 for 및 if 컨텍스트에서 생성된 목록입니다. 표현식에서 튜플을 파생시키려면 괄호를 사용해야 합니다.

여기서 목록의 각 값에 3을 곱하여 새 목록을 얻습니다.

>>> vec = [2, 4, 6]
>>> [3*x for x in vec]
[6, 12, 18]

이제 약간의 트릭을 사용합니다.

>>> [[x, x**2] for x in vec]
[[2, 4], [4, 16], [6, 36]]

여기서 시퀀스의 각 요소에 대해 하나씩 메서드를 호출합니다.

>>> freshfruit = ['  banana', '  loganberry ', 'passion fruit  ']
>>> [weapon.strip() for weapon in freshfruit]
['banana', 'loganberry', 'passion fruit']

우리는 if 절을 필터로 사용:

>>> [3*x for x in vec if x > 3]
[12, 18]
>>> [3*x for x in vec if x < 2]
[]

다음은 루프 및 기타 트릭에 대한 몇 가지 데모입니다.

>>> vec1 = [2, 4, 6]
>>> vec2 = [4, 3, -9]
>>> [x*y for x in vec1 for y in vec2]
[8, 6, -18, 16, 12, -36, 24, 18, -54]
>>> [x+y for x in vec1 for y in vec2]
[6, 5, -7, 8, 7, -5, 10, 9, -3]
>>> [vec1[i]*vec2[i] for i in range(len(vec1))]
[8, 12, -54]

목록 이해는 복잡한 표현식이나 중첩 함수를 사용할 수 있습니다.

>>> [str(round(355/113, i)) for i in range(1, 6)]
['3.1', '3.14', '3.142', '3.1416', '3.14159']

중첩 목록 이해

Python 목록도 중첩될 수 있습니다.

다음 예는 3X4 행렬 목록을 보여줍니다.

>>> matrix = [
...     [1, 2, 3, 4],
...     [5, 6, 7, 8],
...     [9, 10, 11, 12],
... ]

다음 예는 3X4 행렬 목록을 4X3 목록으로 변환합니다.

>>> [[row[i] for row in matrix] for i in range(4)]
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

다음 예는 다음 방법을 사용하여 구현할 수도 있습니다.

>>> transposed = []
>>> for i in range(4):
...     transposed.append([row[i] for row in matrix])
...
>>> transposed
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

다른 구현 방법:

>>> transposed = []
>>> for i in range(4):
...     # the following 3 lines implement the nested listcomp
...     transposed_row = []
...     for row in matrix:
...         transposed_row.append(row[i])
...     transposed.append(transposed_row)
...
>>> transposed
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

del 문

del 문을 사용하면 값 대신 인덱스로 목록에서 요소를 삭제할 수 있습니다. 이는 pop()을 사용하여 값을 반환하는 것과 다릅니다. del 문을 사용하여 목록에서 컷을 삭제하거나 전체 목록을 지울 수 있습니다(이전에 소개한 방법은 빈 목록을 컷에 할당하는 것이었습니다). 예:

>>> a = [-1, 1, 66.25, 333, 333, 1234.5]
>>> del a[0]
>>> a
[1, 66.25, 333, 333, 1234.5]
>>> del a[2:4]
>>> a
[1, 66.25, 1234.5]
>>> del a[:]
>>> a
[]

del을 사용하여 엔터티 변수를 삭제할 수도 있습니다.

>>> del a

튜플 및 시퀀스

튜플은 쉼표로 구분된 여러 값으로 구성됩니다. 예:

>>> t = 12345, 54321, 'hello!'
>>> t[0]
12345
>>> t
(12345, 54321, 'hello!')
>>> # Tuples may be nested:
... u = t, (1, 2, 3, 4, 5)
>>> u
((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))

보시다시피 튜플은 다음과 같은 경우 항상 출력됩니다. 출력 중첩 구조를 올바르게 표현하기 위해 괄호로 묶었습니다. 괄호와 함께 입력할 수도 있고 입력하지 않을 수도 있지만 일반적으로 괄호가 필요합니다(튜플이 더 큰 표현식의 일부인 경우).


Set

세트는 반복되지 않는 요소의 순서가 없는 세트입니다. 기본 기능에는 관계 테스트 및 중복 요소 제거가 포함됩니다.

컬렉션은 중괄호({})를 사용하여 생성할 수 있습니다. 참고: 빈 컬렉션을 생성하려면 {} 대신 set()을 사용해야 합니다. 후자는 다음 섹션에서 소개할 데이터 구조인 빈 사전을 생성합니다.

다음은 간단한 데모입니다:

>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
>>> print(basket)                      # show that duplicates have been removed
{'orange', 'banana', 'pear', 'apple'}
>>> 'orange' in basket                 # fast membership testing
True
>>> 'crabgrass' in basket
False

>>> # Demonstrate set operations on unique letters from two words
...
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a                                  # unique letters in a
{'a', 'r', 'b', 'c', 'd'}
>>> a - b                              # letters in a but not in b
{'r', 'd', 'b'}
>>> a | b                              # letters in either a or b
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
>>> a & b                              # letters in both a and b
{'a', 'c'}
>>> a ^ b                              # letters in a or b but not both
{'r', 'd', 'b', 'm', 'z', 'l'}>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
>>> print(basket)                      # show that duplicates have been removed
{'orange', 'banana', 'pear', 'apple'}
>>> 'orange' in basket                 # fast membership testing
True
>>> 'crabgrass' in basket
False

>>> # Demonstrate set operations on unique letters from two words
...
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a                                  # unique letters in a
{'a', 'r', 'b', 'c', 'd'}
>>> a - b                              # letters in a but not in b
{'r', 'd', 'b'}
>>> a | b                              # letters in either a or b
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
>>> a & b                              # letters in both a and b
{'a', 'c'}
>>> a ^ b                              # letters in a or b but not both
{'r', 'd', 'b', 'm', 'z', 'l'}

컬렉션도 이해력을 지원합니다:

>>> a = {x for x in 'abracadabra' if x not in 'abc'}
>>> a
{'r', 'd'}

Dictionaries

Python의 또 다른 매우 유용한 내장 데이터 유형은 사전입니다.

순서는 연속된 정수로 색인화됩니다. 이와 달리 사전은 키워드로 색인화됩니다. 키워드는 일반적으로 문자열 또는 숫자 값일 수 있습니다.

사전을 이해하는 가장 좋은 방법은 사전을 키 => 값 쌍의 순서 없는 모음으로 생각하는 것입니다. 동일한 사전 내에서 키워드는 서로 달라야 합니다.

중괄호 쌍은 빈 사전({})을 생성합니다.

다음은 사전 사용법의 간단한 예입니다.

>>> tel = {'jack': 4098, 'sape': 4139}
>>> tel['guido'] = 4127
>>> tel
{'sape': 4139, 'guido': 4127, 'jack': 4098}
>>> tel['jack']
4098
>>> del tel['sape']
>>> tel['irv'] = 4127
>>> tel
{'guido': 4127, 'irv': 4127, 'jack': 4098}
>>> list(tel.keys())
['irv', 'guido', 'jack']
>>> sorted(tel.keys())
['guido', 'irv', 'jack']
>>> 'guido' in tel
True
>>> 'jack' not in tel
False

생성자 dict()는 키-값 쌍 튜플 목록에서 직접 사전을 구축합니다. 고정된 패턴이 있는 경우 리스트 컴프리헨션은 특정 키-값 쌍을 지정합니다:

>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
{'sape': 4139, 'jack': 4098, 'guido': 4127}

또한 사전 컴프리헨션을 사용하여 임의의 키와 값의 표현식 사전을 만들 수 있습니다:

>>> {x: x**2 for x in (2, 4, 6)}
{2: 4, 4: 16, 6: 36}

키워드가 단순한 문자열인 경우 key It을 사용하세요. 때로는 단어 매개변수로 키-값 쌍을 지정하는 것이 더 편리합니다:

>>> dict(sape=4139, guido=4127, jack=4098)
{'sape': 4139, 'jack': 4098, 'guido': 4127}

순회 기술

사전에서 순회할 때 키워드와 해당 값은 items() 메소드를 사용하여 동시에 해석될 수 있습니다:

>>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}
>>> for k, v in knights.items():
...     print(k, v)
...
gallahad the pure
robin the brave

시퀀스 내에서 탐색할 때 enumerate() 함수를 사용하여 인덱스 위치와 해당 값을 동시에 얻을 수 있습니다:

>>> for i, v in enumerate(['tic', 'tac', 'toe']):
...     print(i, v)
...
0 tic
1 tac
2 toe

두 개 이상의 시퀀스를 동시에 탐색하려면 zip() 조합을 사용할 수 있습니다:

>>> questions = ['name', 'quest', 'favorite color']
>>> answers = ['lancelot', 'the holy grail', 'blue']
>>> for q, a in zip(questions, answers):
...     print('What is your {0}?  It is {1}.'.format(q, a))
...
What is your name?  It is lancelot.
What is your quest?  It is the holy grail.
What is your favorite color?  It is blue.

To 시퀀스를 역순으로 탐색하려면 먼저 시퀀스를 지정한 다음 reversesd() 함수를 호출하세요.

>>> for i in reversed(range(1, 10, 2)):
...     print(i)
...
9
7
5
3
1

시퀀스를 순서대로 탐색하려면 sorted() 함수를 사용하여 원래 값을 수정하지 않고 정렬된 시퀀스를 반환하세요.

>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> for f in sorted(set(basket)):
...     print(f)
...
apple
banana
orange
pear

문서 보기

  • Python3 목록

  • Python3 Tuple

  • Python3 사전