주제에 대한 기사를 찾고 있습니까 “파이썬 자료 구조“? 웹사이트에서 이 주제에 대한 전체 정보를 제공합니다 c1.castu.org 탐색에서: 새로운 상위 35 가지 팁 업데이트. 바로 아래에서 이 주제에 대한 자세한 답변을 찾을 수 있습니다. 찾고 있는 주제를 더 잘 이해하려면 끝까지 읽으십시오. 더 많은 관련 검색어: 파이썬 자료 구조 파이썬 자료구조와 알고리즘 pdf, 파이썬 자료구조 책, 파이썬 자료구조 pdf, 파이썬 자료구조 강의, 파이썬 자료구조 책 추천, 파이썬 자료구조 종류, 파이썬 자료구조 라이브러리, 파이썬 자료구조 구현
Table of Contents
5. 자료 구조 — Python 3.11.1 문서
자료 구조¶. 이 장에서는 여러분이 이미 배운 것들을 좀 더 자세히 설명하고, 몇 가지 새로운 것들을 덧붙입니다. 5.1. 리스트 더 보기¶. 리스트 자료 형은 몇 가지 …
- Source: docs.python.org
- Views: 2013
- Publish date: 23 hours ago
- Downloads: 53753
- Likes: 7430
- Dislikes: 9
- Title Website: 5. 자료 구조 — Python 3.11.1 문서
- Description Website: 자료 구조¶. 이 장에서는 여러분이 이미 배운 것들을 좀 더 자세히 설명하고, 몇 가지 새로운 것들을 덧붙입니다. 5.1. 리스트 더 보기¶. 리스트 자료 형은 몇 가지 …
- Source: Youtube
- Views: 106089
- Date: 19 hours ago
- Download: 98136
- Likes: 5924
- Dislikes: 1
5. 자료 구조 ¶
5. 자료 구조¶
이 장에서는 여러분이 이미 배운 것들을 좀 더 자세히 설명하고, 몇 가지 새로운 것들을 덧붙입니다.
5.1. 리스트 더 보기¶ 리스트 자료 형은 몇 가지 메서드들을 더 갖고 있습니다. 이것들이 리스트 객체의 모든 메서드 들입니다: list. append ( x ) 리스트의 끝에 항목을 더합니다. a[len(a):] = [x] 와 동등합니다. list. extend ( iterable ) 리스트의 끝에 이터러블의 모든 항목을 덧붙여서 확장합니다. a[len(a):] = iterable 와 동등합니다. list. insert ( i , x ) 주어진 위치에 항목을 삽입합니다. 첫 번째 인자는 삽입되는 요소가 갖게 될 인덱스입니다. 그래서 a.insert(0, x) 는 리스트의 처음에 삽입하고, a.insert(len(a), x) 는 a.append(x) 와 동등합니다. list. remove ( x ) 리스트에서 값이 x 와 같은 첫 번째 항목을 삭제합니다. 그런 항목이 없으면 ValueError 를 일으킵니다. list. pop ( [ i ] ) 리스트에서 주어진 위치에 있는 항목을 삭제하고, 그 항목을 돌려줍니다. 인덱스를 지정하지 않으면, a.pop() 은 리스트의 마지막 항목을 삭제하고 돌려줍니다. (메서드 시그니처에서 i 를 둘러싼 대괄호는 매개변수가 선택적임을 나타냅니다. 그 위치에 대괄호를 입력해야 한다는 뜻이 아닙니다. 이 표기법은 파이썬 라이브러리 레퍼런스에서 지주 등장합니다.) list. clear ( ) 리스트의 모든 항목을 삭제합니다. del a[:] 와 동등합니다. list. index ( x [ , start [ , end ] ] ) 리스트에 있는 항목 중 값이 x 와 같은 첫 번째 것의 0부터 시작하는 인덱스를 돌려줍니다. 그런 항목이 없으면 ValueError 를 일으킵니다. 선택적인 인자 start 와 end 는 슬라이스 표기법처럼 해석되고, 검색을 리스트의 특별한 서브 시퀀스로 제한하는 데 사용됩니다. 돌려주는 인덱스는 start 인자가 아니라 전체 시퀀스의 시작을 기준으로 합니다. list. count ( x ) 리스트에서 x 가 등장하는 횟수를 돌려줍니다. list. sort ( * , key = None , reverse = False ) 리스트의 항목들을 제자리에서 정렬합니다 (인자들은 정렬 커스터마이제이션에 사용될 수 있습니다. 설명은 sorted() 를 보세요). list. reverse ( ) 리스트의 요소들을 제자리에서 뒤집습니다. list. copy ( ) 리스트의 얕은 사본을 돌려줍니다. a[:] 와 동등합니다. 리스트 메서드 대부분을 사용하는 예: >>> fruits = [ ‘orange’ , ‘apple’ , ‘pear’ , ‘banana’ , ‘kiwi’ , ‘apple’ , ‘banana’ ] >>> fruits . count ( ‘apple’ ) 2 >>> fruits . count ( ‘tangerine’ ) 0 >>> fruits . index ( ‘banana’ ) 3 >>> fruits . index ( ‘banana’ , 4 ) # Find next banana starting at position 4 6 >>> fruits . reverse () >>> fruits [‘banana’, ‘apple’, ‘kiwi’, ‘banana’, ‘pear’, ‘apple’, ‘orange’] >>> fruits . append ( ‘grape’ ) >>> fruits [‘banana’, ‘apple’, ‘kiwi’, ‘banana’, ‘pear’, ‘apple’, ‘orange’, ‘grape’] >>> fruits . sort () >>> fruits [‘apple’, ‘apple’, ‘banana’, ‘banana’, ‘grape’, ‘kiwi’, ‘orange’, ‘pear’] >>> fruits . pop () ‘pear’ You might have noticed that methods like insert , remove or sort that only modify the list have no return value printed – they return the default None . This is a design principle for all mutable data structures in Python. 아마도 여러분이 알아챘을 또 다른 사실은 모든 데이터를 정렬하거나 비교할 수는 없다는 것입니다. 예를 들어, 정수를 문자열과 비교할 수 없고 None을 다른 형과 비교할 수 없기 때문에 [None, ‘hello’, 10] 는 정렬되지 않습니다. 또한 정의된 대소 관계가 없는 형이 있습니다. 예를 들어, 3+4j < 5+7j 는 올바른 비교가 아닙니다. 5.1.1. 리스트를 스택으로 사용하기¶ 리스트 메서드들은 리스트를 스택으로 사용하기 쉽게 만드는데, 마지막에 넣은 요소가 처음으로 꺼내지는 요소입니다 (“last-in, first-out”). 스택의 꼭대기에 항목을 넣으려면 append() 를 사용하세요. 스택의 꼭대기에서 값을 꺼내려면 명시적인 인덱스 없이 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] 5.1.2. 리스트를 큐로 사용하기¶ 리스트를 큐로 사용하는 것도 가능한데, 처음으로 넣은 요소가 처음으로 꺼내지는 요소입니다 (“first-in, first-out”); 하지만, 리스트는 이 목적에는 효율적이지 않습니다. 리스트의 끝에 덧붙이거나, 끝에서 꺼내는 것은 빠르지만, 리스트의 머리에 덧붙이거나 머리에서 꺼내는 것은 느립니다 (다른 요소들을 모두 한 칸씩 이동시켜야 하기 때문입니다). 큐를 구현하려면, 양 끝에서의 덧붙이기와 꺼내기가 모두 빠르도록 설계된 collections.deque 를 사용하세요. 예를 들어: >>> 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’]) 5.1.3. 리스트 컴프리헨션¶ 리스트 컴프리헨션은 리스트를 만드는 간결한 방법을 제공합니다. 흔한 용도는, 각 요소가 다른 시퀀스나 이터러블의 멤버들에 어떤 연산을 적용한 결과인 리스트를 만들거나, 어떤 조건을 만족하는 요소들로 구성된 서브 시퀀스를 만드는 것입니다. 예를 들어, 제곱수의 리스트를 만들고 싶다고 가정하자, 이런 식입니다: >>> squares = [] >>> for x in range ( 10 ): … squares . append ( x ** 2 ) … >>> squares [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] 이것은 x 라는 이름의 변수를 만들고 (또는 덮어쓰고) 루프가 종료된 후에도 남아있게 만든다는 것에 유의하세요. 어떤 부작용도 없이, 제곱수의 리스트를 이런 식으로 계산할 수 있습니다: squares = list ( map ( lambda x : x ** 2 , range ( 10 ))) 또는, 이렇게 할 수도 있습니다: squares = [ x ** 2 for x in range ( 10 )] 이것이 더 간결하고 읽기 쉽습니다. 리스트 컴프리헨션은 표현식과 그 뒤를 따르는 for 절과 없거나 여러 개의 for 나 if 절들을 감싸는 대괄호로 구성됩니다. 그 결과는 새 리스트인데, for 와 if 절의 문맥에서 표현식의 값을 구해서 만들어집니다. 예를 들어, 이 리스트 컴프리헨션은 두 리스트의 요소들을 서로 같지 않은 것끼리 결합합니다: >>> [( x , y ) for x in [ 1 , 2 , 3 ] for y in [ 3 , 1 , 4 ] if x != y ] [(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)] 그리고, 이것은 다음과 동등합니다: >>> combs = [] >>> for x in [ 1 , 2 , 3 ]: … for y in [ 3 , 1 , 4 ]: … if x != y : … combs . append (( x , y )) … >>> combs [(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)] 두 코드 조각에서 for 와 if 문의 순서가 같음에 유의하세요. 표현식이 튜플이면 (즉 앞의 예에서 (x, y) ), 반드시 괄호로 둘러싸야 합니다. >>> vec = [ – 4 , – 2 , 0 , 2 , 4 ] >>> # create a new list with the values doubled >>> [ x * 2 for x in vec ] [-8, -4, 0, 4, 8] >>> # filter the list to exclude negative numbers >>> [ x for x in vec if x >= 0 ] [0, 2, 4] >>> # apply a function to all the elements >>> [ abs ( x ) for x in vec ] [4, 2, 0, 2, 4] >>> # call a method on each element >>> freshfruit = [ ‘ banana’ , ‘ loganberry ‘ , ‘passion fruit ‘ ] >>> [ weapon . strip () for weapon in freshfruit ] [‘banana’, ‘loganberry’, ‘passion fruit’] >>> # create a list of 2-tuples like (number, square) >>> [( x , x ** 2 ) for x in range ( 6 )] [(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)] >>> # the tuple must be parenthesized, otherwise an error is raised >>> [ x , x ** 2 for x in range ( 6 )] File “
” , line 1 [ x , x ** 2 for x in range ( 6 )] ^^^^^^^ SyntaxError : did you forget parentheses around the comprehension target? >>> # flatten a list using a listcomp with two ‘for’ >>> vec = [[ 1 , 2 , 3 ], [ 4 , 5 , 6 ], [ 7 , 8 , 9 ]] >>> [ num for elem in vec for num in elem ] [1, 2, 3, 4, 5, 6, 7, 8, 9] 리스트 컴프리헨션은 복잡한 표현식과 중첩된 함수들을 포함할 수 있습니다: >>> from math import pi >>> [ str ( round ( pi , i )) for i in range ( 1 , 6 )] [‘3.1’, ‘3.14’, ‘3.142’, ‘3.1416’, ‘3.14159’] 5.1.4. 중첩된 리스트 컴프리헨션¶ 리스트 컴프리헨션의 첫 표현식으로 임의의 표현식이 올 수 있는데, 다른 리스트 컴프리헨션도 가능합니다. 다음과 같은 길이가 4인 리스트 3개의 리스트로 구현된 3×4 행렬의 예를 봅시다: >>> matrix = [ … [ 1 , 2 , 3 , 4 ], … [ 5 , 6 , 7 , 8 ], … [ 9 , 10 , 11 , 12 ], … ] 다음 리스트 컴프리헨션은 행과 열을 전치 시킵니다: >>> [[ row [ i ] for row in matrix ] for i in range ( 4 )] [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]] As we saw in the previous section, the inner list comprehension is evaluated in the context of the for that follows it, so this example is equivalent to: >>> 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]] 실제 세상에서는, 복잡한 흐름문보다 내장 함수들을 선호해야 합니다. 이 경우에는 zip() 함수가 제 역할을 할 수 있습니다: >>> list ( zip ( * matrix )) [(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)] 이 줄에 나오는 애스터리스크에 대한 자세한 내용은 인자 목록 언 패킹 을 보세요. 5.2. 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 이후에 이름 a 를 참조하는 것은 에러입니다 (적어도 다른 값이 새로 대입되기 전까지). 뒤에서 del 의 다른 용도를 보게 됩니다.
5.3. 튜플과 시퀀스¶ 리스트와 문자열이 인덱싱과 슬라이싱 연산과 같은 많은 성질을 공유함을 보았습니다. 이것들은 시퀀스 자료 형의 두 가지 예입니다 (시퀀스 형 — list, tuple, range 를 보세요). 파이썬은 진화하는 언어이기 때문에, 다른 시퀀스 자료형이 추가될 수도 있습니다. 다른 표준 시퀀스 자료 형이 있습니다: 튜플 입니다. 튜플은 쉼표로 구분되는 여러 값으로 구성됩니다. 예를 들어: >>> 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)) >>> # Tuples are immutable: … t [ 0 ] = 88888 Traceback (most recent call last): File “
” , line 1 , in TypeError : ‘tuple’ object does not support item assignment >>> # but they can contain mutable objects: … v = ([ 1 , 2 , 3 ], [ 3 , 2 , 1 ]) >>> v ([1, 2, 3], [3, 2, 1]) 여러분이 보듯이, 출력되는 튜플은 항상 괄호로 둘러싸입니다, 그래서 중첩된 튜플이 올바르게 해석됩니다; 종종 괄호가 필요하기는 하지만 (튜플이 더 큰 표현식의 일부일 때), 둘러싼 괄호와 함께 또는 없이 입력될 수 있습니다. 튜플의 개별 항목에 대입하는 것은 가능하지 않지만, 리스트 같은 가변 객체를 포함하는 튜플을 만들 수는 있습니다. 튜플이 리스트처럼 보인다 하더라도, 이것들은 다른 상황에서 다른 목적으로 사용됩니다. 튜플은 불변 이고, 보통 이질적인 요소들의 시퀀스를 포함합니다. 요소들은 언 패킹 (이 섹션의 뒤에 나온다) 이나 인덱싱 (또는 네임드 튜플 의 경우는 어트리뷰트로도) 으로 액세스합니다. 리스트는 가변 이고, 요소들은 보통 등질 적이고 리스트에 대한 이터레이션으로 액세스 됩니다. 특별한 문제는 비었거나 하나의 항목을 갖는 튜플을 만드는 것입니다: 이 경우를 수용하기 위해 문법은 추가적인 예외 사항을 갖고 있습니다. 빈 튜플은 빈 괄호 쌍으로 만들어집니다; 하나의 항목으로 구성된 튜플은 값 뒤에 쉼표를 붙여서 만듭니다 (값 하나를 괄호로 둘러싸기만 하는 것으로는 충분하지 않습니다). 추합니다, 하지만 효과적입니다. 예를 들어: >>> empty = () >>> singleton = ‘hello’ , # <-- note trailing comma >>> len ( empty ) 0 >>> len ( singleton ) 1 >>> singleton (‘hello’,) 문장 t = 12345, 54321, ‘hello!’ 는 튜플 패킹 의 예입니다: 값 12345 , 54321 , ‘hello!’ 는 함께 튜플로 패킹 됩니다. 반대 연산 또한 가능합니다: >>> x , y , z = t 이것은, 충분히 적절하게도, 시퀀스 언 패킹 이라고 불리고 오른쪽에 어떤 시퀀스가 와도 됩니다. 시퀀스 언 패킹은 등호의 좌변에 시퀀스에 있는 요소들과 같은 개수의 변수들이 올 것을 요구합니다. 다중 대입은 사실 튜플 패킹과 시퀀스 언 패킹의 조합일뿐이라는 것에 유의하세요. 5.4. 집합¶ 파이썬은 집합 을 위한 자료 형도 포함합니다. 집합은 중복되는 요소가 없는 순서 없는 컬렉션입니다. 기본적인 용도는 멤버십 검사와 중복 엔트리 제거입니다. 집합 객체는 합집합, 교집합, 차집합, 대칭 차집합과 같은 수학적인 연산들도 지원합니다. 집합을 만들 때는 중괄호나 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 a or b or both {‘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’}
5.5. 딕셔너리¶ 파이썬에 내장된 또 하나의 쓸모있는 자료 형은 딕셔너리 입니다 (매핑 형 — dict 를 보세요). 딕셔너리는 종종 다른 언어들에서 “연관 메모리(associative memories)” 나 “연관 배열(associative arrays)” 의 형태로 발견됩니다. 숫자들로 인덱싱되는 시퀀스와 달리, 딕셔너리는 키 로 인덱싱되는데, 모든 불변형을 사용할 수 있습니다; 문자열과 숫자들은 항상 키가 될 수 있습니다. 튜플이 문자열, 숫자, 튜플들만 포함하면, 키로 사용될 수 있습니다; 튜플이 직접적이나 간접적으로 가변 객체를 포함하면, 키로 사용될 수 없습니다. 리스트는 키로 사용할 수 없는데, 리스트는 인덱스 대입, 슬라이스 대입, append() 나 extend() 같은 메서드들로 값이 수정될 수 있기 때문입니다. 딕셔너리를 (한 딕셔너리 안에서) 키가 중복되지 않는다는 제약 조건을 가진 키: 값 쌍의 집합으로 생각하는 것이 최선입니다. 중괄호 쌍은 빈 딕셔너리를 만듭니다: {} . 중괄호 안에 쉼표로 분리된 키:값 쌍들의 목록을 넣으면, 딕셔너리에 초기 키:값 쌍들을 제공합니다; 이것이 딕셔너리가 출력되는 방식이기도 합니다. 딕셔너리의 주 연산은 값을 키와 함께 저장하고 주어진 키로 값을 추출하는 것입니다. del 로 키:값 쌍을 삭제하는 것도 가능합니다. 이미 사용하고 있는 키로 저장하면, 그 키로 저장된 예전 값은 잊힙니다. 존재하지 않는 키로 값을 추출하는 것은 에러입니다. 딕셔러리에 list(d) 를 수행하면 딕셔너리에서 사용되고 있는 모든 키의 리스트를 삽입 순서대로 돌려줍니다 (정렬을 원하면 대신 sorted(d) 를 사용하면 됩니다). 하나의 키가 딕셔너리에 있는지 검사하려면, in 키워드들 사용하세요. 여기에 딕셔너리를 사용하는 조그마한 예가 있습니다: >>> tel = { ‘jack’ : 4098 , ‘sape’ : 4139 } >>> tel [ ‘guido’ ] = 4127 >>> tel {‘jack’: 4098, ‘sape’: 4139, ‘guido’: 4127} >>> tel [ ‘jack’ ] 4098 >>> del tel [ ‘sape’ ] >>> tel [ ‘irv’ ] = 4127 >>> tel {‘jack’: 4098, ‘guido’: 4127, ‘irv’: 4127} >>> list ( tel ) [‘jack’, ‘guido’, ‘irv’] >>> sorted ( tel ) [‘guido’, ‘irv’, ‘jack’] >>> ‘guido’ in tel True >>> ‘jack’ not in tel False dict() 생성자는 키-값 쌍들의 시퀀스로 부터 직접 딕셔너리를 구성합니다. >>> dict ([( ‘sape’ , 4139 ), ( ‘guido’ , 4127 ), ( ‘jack’ , 4098 )]) {‘sape’: 4139, ‘guido’: 4127, ‘jack’: 4098} 이에 더해, 딕셔너리 컴프리헨션은 임의의 키와 값 표현식들로 부터 딕셔너리를 만드는데 사용될 수 있습니다: >>> { x : x ** 2 for x in ( 2 , 4 , 6 )} {2: 4, 4: 16, 6: 36} 키가 간단한 문자열일 때, 때로 키워드 인자들을 사용해서 쌍을 지정하기가 쉽습니다: >>> dict ( sape = 4139 , guido = 4127 , jack = 4098 ) {‘sape’: 4139, ‘guido’: 4127, ‘jack’: 4098}
5.6. 루프 테크닉¶ 딕셔너리로 루핑할 때, 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. 시퀀스를 거꾸로 루핑하려면, 먼저 정방향으로 시퀀스를 지정한 다음에 reversed() 함수를 호출하세요. >>> for i in reversed ( range ( 1 , 10 , 2 )): … print ( i ) … 9 7 5 3 1 정렬된 순서로 시퀀스를 루핑하려면, sorted() 함수를 사용해서 소스를 변경하지 않고도 정렬된 새 리스트를 받을 수 있습니다. >>> basket = [ ‘apple’ , ‘orange’ , ‘apple’ , ‘pear’ , ‘orange’ , ‘banana’ ] >>> for i in sorted ( basket ): … print ( i ) … apple apple banana orange orange pear 시퀀스에 대해 set() 을 사용하면 중복 요소를 제거합니다. 시퀀스에 대해 set() 과 sorted() 를 함께 사용하는 것은 시퀀스의 고유 한 요소를 정렬된 순서로 루핑하는 관용적 방법입니다. >>> basket = [ ‘apple’ , ‘orange’ , ‘apple’ , ‘pear’ , ‘orange’ , ‘banana’ ] >>> for f in sorted ( set ( basket )): … print ( f ) … apple banana orange pear 때로 루프를 돌고 있는 리스트를 변경하고픈 유혹을 느낍니다; 하지만, 종종, 대신 새 리스트를 만드는 것이 더 간단하고 더 안전합니다. >>> import math >>> raw_data = [ 56.2 , float ( ‘NaN’ ), 51.7 , 55.3 , 52.5 , float ( ‘NaN’ ), 47.8 ] >>> filtered_data = [] >>> for value in raw_data : … if not math . isnan ( value ): … filtered_data . append ( value ) … >>> filtered_data [56.2, 51.7, 55.3, 52.5, 47.8]
5.7. 조건 더 보기¶ while 과 if 문에서 사용되는 조건에는 비교뿐만 아니라 모든 연산자를 사용할 수 있습니다. The comparison operators in and not in are membership tests that determine whether a value is in (or not in) a container. The operators is and is not compare whether two objects are really the same object. All comparison operators have the same priority, which is lower than that of all numerical operators. 비교는 연쇄할 수 있습니다. 예를 들어, a < b == c 는, a 가 b 보다 작고, 동시에 b 가 c 와 같은지 검사합니다. 비교는 논리 연산자 and 와 or 를 사용해서 결합할 수 있고, 비교의 결과는 (또는 그 밖의 모든 논리 표현식은) not 으로 부정될 수 있습니다. 이것들은 비교 연산자보다 낮은 우선순위를 갖습니다. 이것 간에는 not 이 가장 높은 우선순위를 갖고, or 가 가장 낮습니다. 그래서 A and not B or C 는 (A and (not B)) or C 와 동등합니다. 여느 때처럼, 원하는 조합을 표현하기 위해 괄호를 사용할 수 있습니다. 논리 연산자 and 와 or 는 소위 단락-회로(short-circuit) 연산자입니다: 인자들은 왼쪽에서 오른쪽으로 값이 구해지고, 결과가 결정되자마자 값 구하기는 중단됩니다. 예를 들어, A 와 C 가 참이고 B 가 거짓이면, A and B and C 는 표현식 C 의 값을 구하지 않습니다. 논리값이 아닌 일반 값으로 사용될 때, 단락-회로 연산자의 반환 값은 마지막으로 값이 구해진 인자입니다. 비교의 결과나 다른 논리 표현식의 결과를 변수에 대입할 수 있습니다. 예를 들어, >>> string1 , string2 , string3 = ” , ‘Trondheim’ , ‘Hammer Dance’ >>> non_null = string1 or string2 or string3 >>> non_null ‘Trondheim’ 파이썬에서, C와는 달리, 표현식 안에서의 대입은 바다코끼리 연산자 := 를 사용하여 명시적으로 수행해야 합니다. C 프로그램에서 흔히 마주치는 부류의 문제들을 회피하도록 합니다: == 를 사용할 표현식에 = 를 입력하는 실수.
파이썬으로 구현하는 자료구조 요약 정리 – 배열(Array), 큐 …
class LinkedList: def __init__(self): self.head = None def add(self, data): new_node = Node(data) if not self.head: self.head = new_node else: node = self.head while node.next: node = node.next node.next = new_node def delete(self, data): node = self.head if node.data == data: self.head = node.next del node else: while node.next: next_node = node.next if next_node.data == data: node.next = next_node.next del next_node else: node = node.next def find(self, data): node = self.head while node: if node.data == data: return node else: node = node.next def print(self): node = self.head while node: print(node.data) node = node.next
class DoublyLinkedList: def __init__(self): self.head = None self.tail = self.head def add(self, data): new_node = Node(data) if not self.head: self.head = new_node self.tail = self.head else: node = self.head while node.next: node = node.next new_node.prev = node node.next = new_node self.tail = new_node
PriorityQueue(): 데이터마다 우선순위를 지정하여, 정렬된 큐로, 우선순위 높은 순으로 출력하는 자료 구조 data_queue = queue.PriorityQueue() data_queue.put((10, 1)) # (10,1) data_queue.put((5, 2)) # (5, 2) – (10,1) data_queue.put((15, 3)) # (5, 2) – (10, 1) – (15,3) data_queue.get() # (5,2) 출력 data_queue.get() # (10, 1) 출력
22 thg 1, 2020 — 대표적인 자료구조로는 배열(Array), 스택(Stack), 큐(Queue), 링크드 리스트(Linked List), 해쉬 테이블(Hash Table), 힙(Heap) 등이 존재합니다. Python …
- Source: davinci-ai.tistory.com
- Views: 88918
- Publish date: 10 minute ago
- Downloads: 33196
- Likes: 4154
- Dislikes: 1
- Title Website: 파이썬으로 구현하는 자료구조 요약 정리 – 배열(Array), 큐 …
- Description Website: 22 thg 1, 2020 — 대표적인 자료구조로는 배열(Array), 스택(Stack), 큐(Queue), 링크드 리스트(Linked List), 해쉬 테이블(Hash Table), 힙(Heap) 등이 존재합니다. Python …
파이썬 자료구조 15min
- Source: Youtube
- Views: 65382
- Date: 3 hours ago
- Download: 104097
- Likes: 476
- Dislikes: 1
배열(Array), 큐(Queue), Stack, Linked List
Writer: Harim Kang
해당 내용은 코딩 테스트 및 기술 면접을 대비하기 위해서 자료구조를 공부하며 정리한 내용입니다. 각각 자료구조의 종류와 특성, 장단점, 파이썬을 이용한 간단한 구현 코드까지 작성하였습니다.
자료구조
정의
대량의 데이터를 효율적으로 관리할 수 있도록 하는 데이터의 구조를 의미합니다.
데이터 특성에 따라서, 체계적인 데이터 구조화가 필요하며, 이러한 데이터 구조는 코드의 효율성, 성능을 결정합니다.
종류
대표적인 자료구조로는 배열(Array), 스택(Stack), 큐(Queue), 링크드 리스트(Linked List), 해쉬 테이블(Hash Table), 힙(Heap) 등이 존재합니다.
Python에서는 대표적으로 List, tuple, set, dictionary가 존재하며, 위의 자료구조 대부분을 모두 구현이 가능합니다.
배열(Array)
배열은 같은 종류의 데이터를 순차적으로 저장하는 자료구조입니다. python에서는 list로 구현이 되어있습니다.
index를 통해 직접 접근이 가능합니다.
장점 : 빠른 접근이 가능하다는 점입니다.
단점 : 데이터 추가와 삭제에 비용이 많이 사용된다는 점입니다. 데이터 추가시, 공간이 많이 필요하며, 삭제 시 빈 공간이 생겨 이를 관리해주어야 합니다. 길이 조절이 어렵다는 단점이 있습니다.
# 1차원 배열 = 리스트 data = [1, 2, 3, 4, 5] string1 = ‘Hello World’ print(data[3]) # 4 출력 print(string1[3]) # l 출력 # 2차원 배열 data2 = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] print(data[1][0]) # 4 출력
예제 : 특정 Alphabet의 빈도수 측정 함수
특정 데이터 세트에서 특정한 알파벳이 몇번이나 사용되었는지를 찾아보는 함수를 작성해보겠습니다.
def find_alphabet(dataset, alphabet): count = 0 for data in dataset: for i in range(len(data)): if data[i] == alphabet: count += 1 print(count)
큐(Queue)
먼저 넣은 데이터를 가장 먼저 꺼는 데이터 구조입니다.
FIFO(First-In, First-Out : 선입선출) 또는 LILO(Last-In, Last-Out) 방식을 사용합니다.
기능
Enqueue : 큐에 데이터를 넣는 기능을 의미합니다. python list의 append() 메서드와 유사합니다.
Dequeue : 큐에서 데이터를 꺼내는 기능을 의미합니다. python list의 pop(0) 메소드와 유사합니다.
종류
Python에서는 queue라이브러리를 제공합니다. 하지만 대부분의 큐와 관련된 자료구조는 list를 통해 구현이 가능합니다.
import queue
Queue(): 일반적인 큐 자료구조 data_queue = queue.Queue() data_queue.put(1) # 1 data_queue.put(2) # 1 – 2 data_queue.put(3) # 1 – 2 – 3 data_queue.get() # 1 출력 data_queue.get() # 2 출력
LifoQueue(): 나중에 입력된 데이터가 먼저 출력되는 구조(Stack과 동일) data_queue = queue.LifoQueue() data_queue.put(1) # 1 data_queue.put(2) # 2 – 1 data_queue.put(3) # 3 – 2 – 1 data_queue.get() # 3 출력 data_queue.get() # 2 출력
PriorityQueue(): 데이터마다 우선순위를 지정하여, 정렬된 큐로, 우선순위 높은 순으로 출력하는 자료 구조 data_queue = queue.PriorityQueue() data_queue.put((10, 1)) # (10,1) data_queue.put((5, 2)) # (5, 2) – (10,1) data_queue.put((15, 3)) # (5, 2) – (10, 1) – (15,3) data_queue.get() # (5,2) 출력 data_queue.get() # (10, 1) 출력
큐는 멀티 테스킹을 위한 프로세스 스케쥴링 방식에 사용된다.
리스트로 Queue 구현
class ListQueue: def __init__(self): self.my_list = list() def put(self, element): self.my_list.append(element) def get(self): return self.my_list.pop(0) def qsize(self): return len(self.my_list)
간단하게 Enqueue기능을 가지는 put 메서드, Dequeue기능을 가진 get 메서드, 큐의 길이를 반환하는 qsize 메서드를 구현한 코드입니다.
리스트로 PriorityQueue 구현
class ListPriorityQueue: def __init__(self): self.my_list = list() def put(self, element): self.my_list.append(element) self.my_list.sort(key=lambda x: x[0]) def get(self): return self.my_list.pop(0) def qsize(self): return len(self.my_list)
list의 메소드 중 하나인, sort를 이용하여 구현하였습니다. lambda함수를 사용하여 첫 번째 원소가 작은 순서로 우선순위를 정렬하였습니다.
스택 (Stack)
가장 나중에 쌓은 데이터를 가정 먼저 뺄 수 있는 데이터 구조입니다. LIFO(Last-In, First-Out)방식을 사용하는 구조입니다.
스택은 내부 프로세스 구조 함수의 동작 방식으로 사용됩니다.
기능
push(): 데이터를 스택에 쌓는 기능을 의미합니다. python list의 append 메소드와 같습니다.
pop(): 데이터를 스택에서 꺼내는 기능을 의미합니다. python list에 같은 기능이 있습니다. data_stack = list()
data_stack.append(1) # [1]
data_stack.append(2) # [1 2]
data_stack.pop() # 2 출력
장단점
장점 구조가 단순하고, 구현이 쉽습니다. 데이터 저장/불러오는 속도가 빠릅니다.
단점 데이터 최대 갯수를 사전에 정해주어야 합니다. (python 재귀 함수는 1000번까지 가능) 저장 공간 낭비가 발생할 수 있습니다. (미리 최대 갯수를 넣을 공간을 확보하기 때문)
단점이 상당히 크기때문에 보통 배열로 대체하여 사용합니다.
리스트로 스택 구현하기
class ListStack: def __init__(self): self.my_list = list() def push(self, data): self.my_list.append(data) def pop(self): return self.my_list.pop()
Linked List
연결 리스트라고도 불리는 링크드 리스트는 배열과 달리 연결되지 않고, 떨어진 곳에 존재하는 데이터를 경로로 지정하여 관리하는 데이터 구조입니다. 파이썬에서는 리스트 자료구조가 링크드 리스트 기능을 모두 지원합니다.
링크드 리스트 1
기능
Node: 데이터 저장 단위로, 데이터 값 + 포인터로 구성되어있습니다.
Pointer: 각 노드 안에서, 다음이나 이전의 노드의 주소를 가지는 값을 의미합니다.
장단점
장점 미리 데이터 공간을 미리 할당할 필요가 없습니다.
단점 연결을 위한 별도 데이터 공간 (아래 예제에서는 next변수)가 필요하므로 효율이 낮습니다. 데이터를 찾는데 접근성이 안 좋아서 속도가 느립니다. 중간 데이터 삭제시, 앞 뒤를 모두 고려하여 재구성하는 코드를 작성해야 합니다.
파이썬으로 Node의 구현
class Node: def __init__(self, data): self.data = data self.next = None
노드는 data를 저장하는 변수와 다음 노드를 가리키는 포인터가 있습니다. 해당 코드에서는 next라는 변수로 두었습니다.
파이썬으로 Linked List의 구현
해당 링크드 리스트에서는 간단한 코드 구현만을 하여, 중간 데이터 삽입 코드는 작성하지 않았습니다.
링크드 리스트 2
class LinkedList: def __init__(self): self.head = None def add(self, data): new_node = Node(data) if not self.head: self.head = new_node else: node = self.head while node.next: node = node.next node.next = new_node def delete(self, data): node = self.head if node.data == data: self.head = node.next del node else: while node.next: next_node = node.next if next_node.data == data: node.next = next_node.next del next_node else: node = node.next def find(self, data): node = self.head while node: if node.data == data: return node else: node = node.next def print(self): node = self.head while node: print(node.data) node = node.next
링크드 리스트에서는 head인 첫 번째 노드 정보만 알면 됩니다. 그리고 데이터들을 받아서 Node를 만들어서 리스트에 추가시켜줄 add함수, node의 data값을 통해 리스트에서 제거하는 delete함수, data값으로 Node를 찾아주는 find함수, 현재 링크드 리스트의 모든 노드의 데이터 값을 출력하는 print함수를 간단하게 구현하였습니다.
사용법
ll = LinkedList() # 링크드 리스트 ll선언 ll.add(1) # 노드 1 리스트에 추가 ll.add(2) # 노드 2 리스트에 추가 ll.add(3) # 노드 3 리스트에 추가 ll.print() # 1 2 3 출력 ll.delete(2) # 노드 2 삭제 ll.print() # 1 3 출력 ll.delete(1) # 노드 1 삭제 ll.print() # 3 출력 ll.delete(3) # 노드 3 삭제 print(ll.head) # None 출력
Doubly Linked List
링크드 리스트 3
이중 연결 리스트라고도 하는 더블 링크드 리스트는 양방향의 노드 주소 값을 모두 가지고 있어서 양 방향으로 탐색이 가능하다는 장점을 가진 링크드 리스트입니다.
class Node: def __init__(self, data): self.data = data self.next = None self.prev = None
기존의 링크드 리스트에서 prev라는 이전의 노드를 가리키는 변수를 추가하면 됩니다.
class DoublyLinkedList: def __init__(self): self.head = None self.tail = self.head def add(self, data): new_node = Node(data) if not self.head: self.head = new_node self.tail = self.head else: node = self.head while node.next: node = node.next new_node.prev = node node.next = new_node self.tail = new_node
이전의 링크드 리스트 클래스에서 init에 tail변수가 추가된 점과 add시, tail변수를 고려해주는 점이 다른 코드입니다. 나머지는 같습니다.
다음 포스팅에서는 해쉬 테이블, 트리, 힙에 관한 내용으로 정리하겠습니다.
Reference
링크드 리스트 1 : wikipedia, https://en.wikipedia.org/wiki/Linked_list
링크드 리스트 2 : wikipedia, https://en.wikipedia.org/wiki/Linked_list
링크드 리스트 3 : wikipedia, https://en.wikipedia.org/wiki/Linked_list
2.1 자료형과 자료 구조 – 실용 파이썬 프로그래밍
>>> 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) >>>
>>> row = [‘AA’, ‘100’, ‘32.20’] >>> cost = row[1] * row[2] Traceback (most recent call last): File “
>>> import csv >>> f = open(‘Data/portfolio.csv’) >>> rows = csv.reader(f) >>> next(rows) [‘name’, ‘shares’, ‘price’] >>> row = next(rows) >>> row [‘AA’, ‘100’, ‘32.20’] >>>
파이썬에는 몇 가지 기본 자료형이 있다. 정수; 부동소수점수; 문자열(텍스트) … 튜플은 주로 단순한 레코드 또는 자료 구조를 표현하는 데 사용한다.
- Source: wikidocs.net
- Views: 69684
- Publish date: 23 minute ago
- Downloads: 16192
- Likes: 4736
- Dislikes: 9
- Title Website: 2.1 자료형과 자료 구조 – 실용 파이썬 프로그래밍
- Description Website: 파이썬에는 몇 가지 기본 자료형이 있다. 정수; 부동소수점수; 문자열(텍스트) … 튜플은 주로 단순한 레코드 또는 자료 구조를 표현하는 데 사용한다.
파이썬 코딩 무료 강의 #4 – 자료구조, 스택, 큐, 튜플, 집합, 딕셔너리
- Source: Youtube
- Views: 56680
- Date: 60 minute ago
- Download: 49861
- Likes: 4113
- Dislikes: 9
2.1 자료형과 자료 구조
이 섹션에서는 튜플과 딕셔너리 자료형을 소개한다.
기본 자료형
파이썬에는 몇 가지 기본 자료형이 있다.
정수
부동소수점수
문자열(텍스트)
이런 것들을 도입에서 배웠다.
None 타입
email_address = None
None 은 주로 선택적인 값이나 누락값(missing value)을 표시하는 데 사용된다. 조건문에서는 False 로 평가한다.
if email_address: send_email(email_address, msg)
자료형
실제 프로그램에서는 더 복잡한 자료형을 사용한다. 주식 보유에 대한 정보의 예를 살펴 보자.
구글(GOOG) 주식을 490.10 달러에 100주 보유
이 “객체”는 세 부분으로 구성된다.
종목명 또는 심벌(문자열 “GOOG”)
주식 수(정수 100)
가격(부동소수점수 490.10)
튜플(Tuple)
튜플은 함께 묶인 값의 컬렉션이다.
예:
s = (‘GOOG’, 100, 490.1)
다음과 같이 () 를 생략하기도 한다.
s = ‘GOOG’, 100, 490.1
특수한 사례(0-튜플, 1-튜플).
t = () # 빈 튜플 w = (‘GOOG’, ) # 항목이 한 개 있는 튜플
튜플은 주로 단순한 레코드 또는 자료 구조를 표현하는 데 사용한다. 일반적으로 여러 부분으로 된 단일 객체다. 좋은 비유: 튜플은 데이터베이스 테이블의 단일 행과 비슷하다.
튜플의 항목은 순서가 있다(배열과 비슷함).
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])
튜플로 묶기(packing)
튜플은 서로 관련된 항목들을 단일 엔티티(entity)로 묶는 역할을 한다.
s = (‘GOOG’, 100, 490.1)
튜플을 단일 객체로서 프로그램의 다른 부분으로 쉽게 전달할 수 있다.
튜플을 풀기(unpacking)
튜플을 전달받은 후에는 풀어서 각각의 변수를 사용할 수 있다.
name, shares, price = s print(‘Cost’, shares * price)
왼쪽의 변수 개수가 튜플 구조와 일치해야 한다.
name, shares = s # 오류 Traceback (most recent call last): … ValueError: too many values to unpack
튜플 vs. 리스트
튜플은 읽기 전용 리스트처럼 보인다. 그러나, 튜플의 주된 용도는 여러 부분으로 구성된 단일 항목으로서 사용하는 것이다. 리스트는 고유한 항목들의 컬렉션으로 사용되며, 이때 모든 항목이 같은 타입인 경우가 많다.
record = (‘GOOG’, 100, 490.1) # 포트폴리오의 한 레코드를 나타내는 튜플 symbols = [ ‘GOOG’, ‘AAPL’, ‘IBM’ ] # 세 가지 주식 심벌을 나타내는 리스트
딕셔너리(Dictionary)
딕셔너리는 키(key)를 값(value)에 대응(mapping)시킨다. 해시 테이블(hash table) 또는 연관 배열(associative array)이라고도 부른다. 키는 값에 접근하는 인덱스 역할을 한다.
s = { ‘name’: ‘GOOG’, ‘shares’: 100, ‘price’: 490.1 }
공통적인 연산
딕셔너리에서 값을 얻으려면 키 이름을 사용한다.
>>> print(s[‘name’], s[‘shares’]) GOOG 100 >>> s[‘price’] 490.10 >>>
값을 추가하거나 수정할 때 키 이름을 사용한다.
>>> s[‘shares’] = 75 >>> s[‘date’] = ‘6/6/2007’ >>>
값을 삭제하려면 del 문을 사용한다.
>>> del s[‘date’] >>>
딕셔너리를 사용하는 이유
딕셔너리는 서로 다른 값이 많이 있고 그 값들을 수정 또는 조작해야 할 때 유용하다. 딕셔너리를 사용하면 코드의 가독성이 높아진다.
s[‘price’] # vs s[2]
연습 문제
지난 몇 개의 연습 문제에서, 데이터파일 Data/portfolio.csv 를 읽는 프로그램을 작성했다. csv 모듈을 사용하면 파일을 행 단위로 쉽게 읽을 수 있다.
>>> import csv >>> f = open(‘Data/portfolio.csv’) >>> rows = csv.reader(f) >>> next(rows) [‘name’, ‘shares’, ‘price’] >>> row = next(rows) >>> row [‘AA’, ‘100’, ‘32.20’] >>>
파일을 읽는 것은 쉽지만, 데이터를 읽은 다음에는 그것을 가지고 더 많은 일을 하고 싶을 때가 있다. 예를 들어, 읽은 데이터를 저장하고 계산을 수행하고 싶을 것이다. 하지만, 원시 “행(row)” 데이터만으로는 작업하기에 충분하지 않다. 예를 들어, 간단한 수학 계산도 할 수 없다.
>>> row = [‘AA’, ‘100’, ‘32.20’] >>> cost = row[1] * row[2] Traceback (most recent call last): File “
“, line 1, in TypeError: can’t multiply sequence by non-int of type ‘str’ >>> 원시 데이터를 좀 더 유용한 객체로 바꿔야 나중에 작업에 사용할 수 있다. 튜플이나 딕셔너리를 사용하면 된다.
연습 문제 2.1: 튜플
상호작용적인 프롬프트에서, 다음과 같이 위의 행을 나타내는 튜플을 생성하되, 숫자 컬럼은 적절한 숫자로 변환한다.
>>> t = (row[0], int(row[1]), float(row[2])) >>> t (‘AA’, 100, 32.2) >>>
이것을 사용해, 주식수와 가격을 곱한 총비용을 계산할 수 있다.
>>> cost = t[1] * t[2] >>> cost 3220.0000000000005 >>>
파이썬에서 수학 계산이 틀린가? 답이 왜 3220.0000000000005라고 나올까?
이것은 컴퓨터의 부동소수점 하드웨어로 계산한 결과다. 십진수(decimal)를 십진법(Base-10)이 아니라 이진법(Base-2)으로 표현하기 때문에 이런 결과가 나왔다. 간단한 계산이라 할지라도, 십진수와 관련된 계산에는 작은 오류가 발생한다. 처음 본다면 놀라울 수 있겠지만, 이것은 정상적인 작동이다.
부동소수점 십진수를 사용하는 모든 프로그래밍 언어에서 발생하는 일이지만, 프린팅 과정에서 종종 숨겨진다. 예:
>>> print(f'{cost:0.2f}’) 3220.00 >>>
튜플은 읽기 전용이다. 확인해 보고 싶으면 주식 수를 75로 바꿔보라.
>>> t[1] = 75 Traceback (most recent call last): File “
“, line 1, in 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: 자료 구조로서의 딕셔너리
튜플 대신 딕셔너리를 생성할 수 있다.
>>> 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() 를 다시 호출하지 않았음에도 ‘account’ 가 keys 에서 사라진 것에 유의하라.
키와 값을 함께 다루는 더욱 우아한 방법은 items() 메서드를 사용하는 것이다. 이 메서드를 사용해 (키, 값) 튜플을 얻을 수 있다.
>>> 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() 함수를 사용해 딕셔너리를 생성할 수 있다. 한번 해 보자.
파이썬 자료구조 강좌소개 – edwith
파이썬 자료구조. … 커넥트재단은 ‘커넥트 번역 서포터즈’와 함께 Python for Everybody 강의를 번역하여 제공합니다. 퀴즈를 제외한 모든 강의의 저작권은 Charles …
- Source: www.edwith.org
- Views: 88078
- Publish date: 4 hours ago
- Downloads: 17407
- Likes: 1650
- Dislikes: 5
- Title Website: 파이썬 자료구조 강좌소개 – edwith
- Description Website: 파이썬 자료구조. … 커넥트재단은 ‘커넥트 번역 서포터즈’와 함께 Python for Everybody 강의를 번역하여 제공합니다. 퀴즈를 제외한 모든 강의의 저작권은 Charles …
heapq 내장 모듈로 힙 자료구조 사용하기 | 달레의 파이썬 프로그래밍
- Source: Youtube
- Views: 81215
- Date: 4 hours ago
- Download: 36266
- Likes: 3553
- Dislikes: 8
[개발로그 Python] 데이터 구조 – No.6 – 마이자몽
d = { ‘name’: ‘tom’, ‘age’: 30 } # dictionary에 key의 존재여부 확인 print(‘name’ in d) # True print(‘name’ not in d) # False # dictionary (key, value) 형식으로 데이터 추출 print(d.items()) # dict_items([(‘name’, ‘tom’), (‘age’, 30)]) # dictionary key 값들을 추출한다. print(d.keys()) # dict_keys([‘name’, ‘age’]) # dictionary value 값드을 추출한다. print(d.values()) # dict_values([‘tom’, 30]) # dictionary의 value를 key값으로부터 얻을 수 있다. # key가 없는 경우 default로 None을 반환하고 2번째 인자를 지정해주면 해당 값을 반환한다. print(d.get(‘name’)) # tome print(d.get(‘height’)) # None print(d.get(‘height’, 123)) # 123 # dictionary의 데이터를 수정한다. # 이미 존재하는 key이면 overwrite하고 없으면 추가한다. d.update({‘age’: 20}) print(d) # {‘name’: ‘tom’, ‘age’: 20} # key에 해당하는 값을 반환하고 dictionary에서 삭제한다. # key가 없으면 오류를 발생시킨다. # 2번째 인가자 지정되어 있으면 오류가 아닌 해당 값을 반환한다. # popitem 함수는 같은 기능이지만 값이 아닌 key:value 아이템을 반환한다. print(d.pop(‘age’)) # 20 print(d) # {‘name’: ‘tom’} print(d.pop(‘age’)) # KeyError: ‘age’ print(d.pop(‘age’, 123)) # 123 # dictionary 데이터 모두 삭제 d.clear() print(d) # {}
fruits = {‘apple’, ‘lemon’, ‘watermelon’, ‘apple’} print(fruits) # {‘lemon’, ‘watermelon’, ‘apple’} 순서가 없으므로 출력이 매번 변경됩니다. # 세트에 추가하기 fruits.add(‘melon’) print(fruits) # {‘apple’, ‘melon’, ‘lemon’, ‘watermelon’} # 세트에 모든 엘러멘트 추가하기 fruits.update([‘grape’, ‘watermelon’, ‘mango’]) print(fruits) # {‘melon’, ‘apple’, ‘lemon’, ‘mango’, ‘grape’, ‘watermelon’} # 세트에서 제거하기(매개변수로 받은 값이 세트에 없으면 오류가 발생한다.) fruits.remove(‘grape’) print(fruits) # {‘apple’, ‘watermelon’, ‘lemon’, ‘mango’, ‘melon’} # fruits.remove(‘grape’) # KeyError: ‘grape’ # 세트에서 제거하기(매개변수로 받은 값이 세트에 있으면 삭제한다. 오류가 발생하지 않는다.) fruits.discard(‘watermelon’) print(fruits) # {‘lemon’, ‘melon’, ‘mango’, ‘apple’} fruits.discard(‘watermelon’) # 세트에서 무작위로 값을 반환하고 제거한다. print(fruits.pop()) # 무작위로 값이 나오기 때문에 어떤 값이 나올지 모른다. # 세트에서 모든 값을 제거한다. fruits.clear() print(fruits) # set()
5 thg 6, 2021 — Python 3.9.5 버전을 사용했습니다. 데이터 구조(Data Structure)란? 데이터 구조는 여러 데이터를 효율적으로 저장하기 위해 하나의 집합으로 데이터 …
- Source: myjamong.tistory.com
- Views: 72556
- Publish date: 58 minute ago
- Downloads: 107151
- Likes: 416
- Dislikes: 3
- Title Website: [개발로그 Python] 데이터 구조 – No.6 – 마이자몽
- Description Website: 5 thg 6, 2021 — Python 3.9.5 버전을 사용했습니다. 데이터 구조(Data Structure)란? 데이터 구조는 여러 데이터를 효율적으로 저장하기 위해 하나의 집합으로 데이터 …
초단기 속성 코딩 / 프로그래밍 강좌 (파이썬) – 자료구조 (리스트, 튜플, 딕셔너리)
- Source: Youtube
- Views: 68035
- Date: 7 hours ago
- Download: 35487
- Likes: 2258
- Dislikes: 10
[개발로그 Python] 데이터 구조 – No.6
Python 3.9.5 버전을 사용했습니다.
데이터 구조(Data Structure)란?
데이터 구조는 여러 데이터를 효율적으로 저장하기 위해 하나의 집합으로 데이터를 저장하는 구조(structure) 입니다. 이전에 변수에 숫자나 문자 형태의 데이터 타입을 저장했었는데… 과일들의 집합 처럼 연관된 데이터를 모두 각각 다른 변수로 선언을 해줘야할까요?
# 각각 변수로 선언 fruit1 = ‘수박’ fruit2 = ‘참외’ fruit3 = ‘자몽’ fruit4 = ‘멜론’ # 데이터 구조인 리스트를 사용해서 선언 fruits = [‘수박’, ‘참외’, ‘자몽’, ‘멜론’]
위의 이미지를 코드화한 내용입니다. 연관된 데이터를 각각 변수로 만들지 않고 데이터 구조 중 하나인 list를 만들어서 하나의 변수에서 관리하면 편리하게 사용할 수 있습니다.
Python의 데이터 구조
Python에서 제공해주는 데이터 구조는 아래와 같습니다.
List
Tuple
Set
Dictionary
이번 글에서는 위 4가지 데이터 구조에 대해서 알아보겠습니다.
List (리스트)
다른 언어에서는 Array(배열)라고 합니다. 수학적 의미에서의 배열과 같이 생각하시면 될 것 같고 리스트는 데이터를 순차적으로 저장해서 사용할 수 있는 데이터 구조입니다.
List 읽기
리스트의 인덱스
# 과일을 담은 리스트 fruits = [‘수박’, ‘참외’, ‘자몽’, ‘멜론’] # len 함수를 통해 리스트의 길이를 확인할 수 있습니다. print(len(fruits)) # 4 print(fruits[0]) # 수박 print(fruits[1]) # 참외 print(fruits[2]) # 자몽 print(fruits[3]) # 멜론 print(fruits[4]) # IndexError: list index out of range print(fruits[-1]) # 멜론 print(fruits[-2]) # 자몽 print(fruits[-3]) # 참외 print(fruits[-4]) # 수박 print(fruits[-5]) # IndexError: list index out of range
리스트 타입으로 정의된 데이터는 순차적으로 데이터를 저장하고 대괄호([])에 인덱스를 넣어서 값을 호출 할 수 있습니다. 인덱스는 0부터 시작해서 값을 호출할 때 주의해야합니다. 리스트의 길이가 4인 경우 인덱스는 0 ~ 3까지이고 4를 넣어서 호출하는 경우 오류가 발생합니다.
Python에는 음수의 인덱스도 사용할 수 있습니다. 양수 인덱스와는 반대로 -1부터 시작하고 리스트의 끝에서부터 데이터를 읽습니다. 마찬가지로 리스트의 길이를 벗어나면 오류가 발생합니다.
List 데이터 내장된 함수로 제어
# 과일을 담은 리스트 fruits = [‘수박’, ‘참외’, ‘자몽’, ‘멜론’] # 리스트 끝에 추가 fruits.append(‘망고’) print(fruits) # [‘수박’, ‘참외’, ‘자몽’, ‘멜론’, ‘망고’] # 리스트 특정 위치에 삽입 –> 지정한 인덱스에 값을 저장한다. fruits.insert(2, ‘망고’) print(fruits) # [‘수박’, ‘참외’, ‘망고’, ‘자몽’, ‘멜론’, ‘망고’] # 리스트에서 값으로 제거(첫번 째 값 만 제거된다) fruits.remove(‘망고’) print(fruits) # [‘수박’, ‘참외’, ‘자몽’, ‘멜론’, ‘망고’] # 리스트에서 인덱스로 값 제거하고 반환한다 print(fruits.pop(4)) # 망고 print(fruits) # [‘수박’, ‘참외’, ‘자몽’, ‘멜론’] # 리스트 역순으로 재배치한다. fruits.reverse() print(fruits) # [‘멜론’, ‘자몽’, ‘참외’, ‘수박’] # 리스트의 모든 값을 제거한다. fruits.clear() print(fruits) # []
리스트의 데이터를 내장되어 있는 함수로 제어할 수 있습니다. 각각 설명은 실습으로 대체하겠습니다.
Python Slicing 개념
Python에는 List 처럼 연속적인 데이터를 갖는 객체들에 slicing이라는 강력한 기능을 사용할 수 있습니다. slicing은 자르다의 의미를 갖고 있는데… 말 그대로 범위를 지정해서 선택할 수 있는 기능 입니다.
start : slicing의 시작 위치 (해당 인덱스는 포함한다.)
end : sliceing의 끝 위치 (해당 인덱스는 포함하지 않는다.)
step : 폭 (인덱스의 차이)
# 과일을 담은 리스트 fruits = [‘수박’, ‘참외’, ‘자몽’, ‘멜론’] # 인덱스 2 전까지 범위로 한다. print(fruits[:2]) # [‘수박’, ‘참외’] # 인덱스 2를 포함해서 끝까지 범위로 한다. print(fruits[2:]) # [‘자몽’, ‘멜론’] # 인덱스 1부터 4 전까지 범위로 한다. print(fruits[1:4]) # [‘참외’, ‘자몽’, ‘멜론’] # 인덱스 0 부터 4 전까지 범위로 잡고 2개씩 건너 뛴다. print(fruits[0:4:2]) # [‘수박’, ‘자몽’]
예제를 통해서 익힌다.
다른 언어를 사용해보셨으면 느끼시겠지만… 이런 문자열 관련제어는 Python이 문법적으로 정말 쉽게할 수 있습니다. Python에서 한줄이면 해결할 수 있는 것을 다른 언어에서는 4~5 줄 정도 작성해야합니다.
del 예약어
인덱스로 리스트의 값을 제거하는 방법으로 del 예약어를 사용하는 방법이 있습니다. 리스트의 pop 메소드와의 차이는 값을 반환해주지 않는 다는 점입니다. 그리고 slicing을 통해서 범위로 값을 삭제할 수 있습니다.
# 과일을 담은 리스트 fruits = [‘수박’, ‘참외’, ‘자몽’, ‘멜론’] # 인덱스 1의 값을 삭제한다. del fruits[1] print(fruits) # [‘수박’, ‘자몽’, ‘멜론’] # 인덱스 1부터 3 전까지의 범위를 삭제한다. del fruits[1:3] print(fruits) # [‘수박’] # 리스트의 모든 값을 삭제한다. –> clear함수와 동등합니다. del fruits[:] print(fruits) # []
실습을 통해 확인한다.
List 타입 참조
x = 100 print(id(x)) # 4427777488 y = 100 print(id(y)) # 4427777488
Python에서는 모든 것이 오브젝트로 되어 있다고 했습니다. 그래서 100이라는 객체를 두개의 변수가 바라보면 같은 객체를 바라봅니다. 리스트를 생성해서 사용할 때도 마찬가지만… 다만 조금 다르게 이해해야하는 부분이 있습니다.
x = [1, 2, 3] print(id(x)) # 4330506944 y = [1, 2, 3] print(id(y)) # 4330825600
변수에 숫자형 데이터를 할당해줬을 때와 달리… 똑같은 데이터를 넣은 리스트를 각각 x와 y에 할당해 줬을 때… 둘은 같은 객체일까요? 정답은 다른 객체 입니다. 이는 Python에서 내부적으로 list 데이터 구조로 변수를 초기화해주면 무조건 메모리에 새롭게 객체를 할당하게끔 한 것이고 이렇게 해야하는 이유도 있습니다.
x = [1, 2, 3] y = x y.append(4) print(x) # [1, 2, 3, 4] print(y) # [1, 2, 3, 4]
x라는 리스트를 초기화 시켜주고 y라는 변수에 x와 똑같은 값이 들어가는 리스트를 만들어 줬습니다. x와 y는 따로 데이터를 제어할 수 있도록 해야하는데… x와 y는 같은 객체를 바라보고 있기 때문에 y를 변경했는데 x도 변경된 리스트를 보여주고 있죠. 숫자형 데이터 타입처럼 만약 리스트의 값이 같을 때 같은 객체를 참조하면… 위와 같이 변경되면 안되는 데이터가 변경되버리는 문제가 발생합니다. 그래서 리스트는 초기화 해줄 때 마다 새로운 메모리에 데이터를 할당합니다.
x = [1, 2, 3] # 함수를 이용한 리스트 복사 y = x.copy() y.append(4) # slicing을 이용한 리스트 복사 z = x[:] z.append(5) print(x) # [1, 2, 3, 4] print(y) # [1, 2, 3] print(z) # [1, 2, 3, 5]
이미 존재하는 리스트를 별개의 객체로 복사하기 위해 Python에서는 위와 같이 2가지 방법을 제공하고 있습니다.
리스트 연산
w = [1, 2, 3] print(id(w)) # 4528143040 x = [3, 4, 5] print(id(x)) # 4528461952 y = w + x print(y) # [1, 2, 3, 3, 4, 5] print(id(y)) # 4528462016 z = y * 2 print(z) # [1, 2, 3, 3, 4, 5, 1, 2, 3, 3, 4, 5] print(id(z)) # 4528143232
리스트에서는 더하기와 곱셈 연산을 할 수 있습니다. 리스트에 연산을 하는 경우 기존 객체의 값을 수정하는 것이 아니라… 변경된 데이터를 새로운 객체를 메모리에 할당해서 리스트를 생성해줍니다.
immutable과 mutable
데이터 타입에 대한 글에서 숫자, 문자형 데이터는 변할 수 없는(immutable) 데이터라고 설명한 적 있습니다. 리스트의 경우 변할 수 있는(mutable) 데이터 입니다.
x = [1, 2, 3] print(id(x)) # 4377230016 x.append(4) print(id(x)) # 4377230016
예제에서 볼 수 있듯이… 리스트에 4를 넣어줘서 데이터가 변했습니다. 그런데 객체의 주소는 그대로 똑같습니다. 이런게 mutable하다는 뜻 입니다. 이번에는 mutable한 리스트와 immutable한 문자형 데이터 타입을 비교해서 이해를 돕겠습니다.
# mutable한 list x = [1, 2, 3] print(id(x)) # 4425165504 x[-1] = 5 print(x) # [1, 2, 5] print(id(x)) # 4425165504 # immutable한 문자형 타입 text = ‘myjamong’ print(text[-1]) # g text[-1] = ‘a’ # TypeError: ‘str’ object does not support item assignment
예제에서 볼 수 있듯이 리스트에서 데이터를 변경했을 때 똑같은 객체 주소를 바라보고 데이터를 변경할 수 있는 것을 확인 했습니다. 이는 리스트 데이터 구조가 mutable하기 때문 입니다. 그런데 문자형 데이터인 text 변수는 타입 오류가 발생합니다. 문자형 데이터도 리스트처럼 인덱스를 이용해서 문자열의 일부 데이터를 읽을 수 있는데 수정하는 것은 안됩니다. 이는 문자형 데이터 타입은 immutable하기 때문입니다.
List의 다양성
x = [1, 2.5, ‘자몽’, [1, 2, 3]]
Python의 List는 타입에 대한 제한이 없습니다. Java난 C의 경우 하나의 배열에는 한 가지 타입의 데이터만 들어갈 수 있는데 Python에서는 모든 타입을 같이 들고 있는 리스트를 만들 수 있습니다. 위의 예시처럼 정수, 실수, 문자열, 리스트안에 리스트를 같이 리스트에 넣어서 사용할 수 있습니다.
list_2d = [ [1, 2, 3], [4, 5], [7, 8, 9] ]
배열안에 배열을 중첩해서 넣어서 2차 3차 배열 등 고차 배열을 만들어 사용할 수 있습니다.
list는 python으로 개발하면서 가장 많이 사용되는 데이터 구조가 될겁니다. 그만큼 중요하니 충분히 이해하고 넘어가는 것이 좋습니다.
x = [] print(x) # [] x = list() # [] print(x)
빈 리스트를 생성해서 사용할 수 있습니다. 아직 어떤 데이터를 넣어야할지 정하지 않았을 때 빈 리스트를 생성해서 사용할 수 있습니다.
Tuple(튜플)
Tuple은 immutable한 list입니다. list와 똑같이 인덱스를 이용해서 읽을 수 있고 데이터가 순차적으로 되어 있는 데이터 구조입니다.
# 소괄호를 이용한 튜플 초기화 t = (1, 2, 3, 4, 5) print(type(t)) #
print(t) # (1, 2, 3, 4, 5) # 괄호 없는 튜플 초기화 t = 1, 2, 3, 4, 5 print(type(t)) # print(t) # (1, 2, 3, 4, 5) 리스트는 대괄호를 이용해서 선언했다면… 튜플을 소괄호를 이용하거나 괄호 없이 콤마를 이용해서 초기화할 수 있습니다. 리스트와는 다르게 immutable하기 때문에 append나 remove와 같이 데이터를 변경하는 함수를 사용할 수 없고 직접 인덱스에 접근해서 데이터를 수정할수도 없습니다.
그럼… 이런 튜플을 왜 사용하는 것 일까요? 왜 immutable한 list가 필요한 것 일까요?
Tuple을 사용하는 이유
import sys import timeit # list 생성 속도 start_time = timeit.default_timer() l = [1, 2, 3, 4, 5] print(‘list 생성 속도 : ‘, format(timeit.default_timer() – start_time, ‘.10f’)) # tuple 생성 속도 : 0.0000008920 # tuple 생성 속도 start_time = timeit.default_timer() t = (1, 2, 3, 4, 5) print(‘tuple 생성 속도 : ‘, format(timeit.default_timer() – start_time, ‘.10f’)) # tuple 생성 속도 : 0.0000005320 “”” list : 0.0000008920 tuple : 0.0000005320 –> tuple이 list보다 약 40% 빠르다. “”” # list 데이터 접근 속도 start_time = timeit.default_timer() print(l[1]) # 2 print(‘list 데이터 접근 속도 : ‘, format(timeit.default_timer() – start_time, ‘.10f’)) # list 데이터 접근 속도 : 0.0000039290 # tuple 데이터 접근 속도 start_time = timeit.default_timer() print(t[1]) # 2 print(‘tuple 데이터 접근 속도 : ‘, format(timeit.default_timer() – start_time, ‘.10f’)) # tuple 데이터 접근 속도 : 0.0000029280 “”” list : 0.0000039290 tuple : 0.0000029280 –> tuple 이 list보다 약 25% 빠르다. “”” # 사용하는 메모리 크기 비교 print(‘list의 메모리 크기 : ‘, sys.getsizeof(l)) # list의 메모리 크기 : 120 print(‘tuple의 메모리 크기 : ‘, sys.getsizeof(t)) # tuple의 메모리 크기 : 80 “”” list : 120 tuple : 80 –> tuple이 list 보다 약 33% 메모리 용량을 덜 차지한다. “””
성능의 차이가 있다는 것이 가장 큰 차이 입니다. list와는 다르게 tuple은 immutable하기 때문에 append나 remove처럼 데이터를 제어하는 메소드를 객체에서 갖고 있지 않습니다. 그러다보니 메모리에서는 상대적은 적은 공간을 차지하게 될 것이고 객체를 생성하거나 탐색할 때 더 적은 시간이 소요됩니다.
위 예시 에서는 sys와 timeit 모듈을 사용해서 list와 tuple의 생성 속도, 접근 속도 그리고 메모리 사용 크기를 비교 했습니다. 데이터의 양이 크지 않아 많은 차이는 없지만… tuple이 list 보다 더 빠르고 효율적으로 리소스를 활용하고 있는 것을 볼 수 있습니다. 큰 데이터를 다룰수록 차이는 점점 벌어질 것 입니다.
이런 이유로 순차적인 데이터를 변경할 필요가 없는 경우… list보다는 tuple을 사용하는 것을 고려해볼 수 있습니다.
tuple의 packing과 unpacking
tuple은 데이터가 변하지 않는 경우 사용되지만… 데이터 타입이 다른 경우에도 많이 사용되기도 합니다. 대표적인 예로 tuple의 packing과 unpacking을 이용할 때 다른 데이터 타입을 사용합니다.
# tuple packing result = ‘수학’, 100, ‘영어’, 95.5 # tuple unpacking math, m_score, english, e_score = result # 함수의 반환값을 tuple packing def report(x, y): result = ‘불합격’ is_smart = False if x + y > 90: result = ‘합격’ is_smart = True return result, is_smart, x + y # 함수의 반환값을 tuple unpacking pass_result, smart_bool, score = report(50, 45) print(pass_result, smart_bool, score) # 합격 True 95
packing : 튜플로 데이터를 묶어주는 것을 패킹이라고 힙니다. 즉 튜플로 데이터들을 할당해주는 것이 packing 입니다.
unpacking : 튜플의 데이터를 풀어서 각각 변수에 할당해주는 것이 unpacking입니다.
이런 tuple의 packing과 unpacking을 함수의 반환값을 처리할 때 가장 많이 사용합니다. 함수에 대한 내용은 이 후 글에서 자세히 다룰 것이고 지금은 “함수란 것이 있다” 정도로만 이해하면 될 것 같습니다. 위의 예제에서는 x, y를 기준으로 합격 불합격에 대한 결과와 똑똑한지의 여부와 합산 값을 반환해주는 함수(report)를 사용했습니다.
return할 때 3개의 값(result, is_smart, x + y)을 packing해주고 함수를 호출해서 3개의 값을 unpacking해서 3개의 변수에(pass_result, smart_result, score) 할당해줬습니다.
여러 모듈에 작성된 함수들이 이런식으로 tuple의 packing과 unpacking을 이용해서 값을 반환해주고 있습니다. 잘 활용하면 유용하게 사용될 수 있습니다.
tuple 사용 시 주의사항
# string type t = ‘jamong’ print(type(t)) #
# tuple type t = ‘jamong’, print(type(t)) # 데이터가 하나만 들어 있는 튜플을 생성하고 소괄호를 이용하지 않는 경우 꼭 끝에 ‘,’를 붙여줘야한다. 붙여주지 않으면 튜플이 아닌 다른 타입으로 인식할 수 있습니다.
# tuple내에 mutable한 타입의 데이터는 데이터 변경이 가능하다. t = (100, ‘text’, [‘apple’, ‘lemon’]) t[2][0] = ‘grape’ print(t) # (100, ‘text’, [‘grape’, ‘lemon’]) # tuple의 데이터는 immutable하기 때문에 변경이 불가능하다. t[2] = [‘watermelon’] # TypeError: ‘tuple’ object does not support item assignment
Python의 모든 것이 오브젝트로 되어 있는 특징이 있기 때문에… 위에 처럼 tuple내의 mutable한 데이터는 변경할 수 있다는 것을 암시적으로 알 수 있습니다. tuple의 값들이 각 객체기 때문에… 객체를 변경하는 것이 아니고 객체 내부의 값들을 변경하는 mutable한 데이터라면 변경이 가능하겠죠?
Set(세트)
세트는 순서가 없고 중복이 없는 데이터 집합입니다. 과일 가계에서 판매하고 있는 과일들의 종류를 알기 위해 사용한다던가… 회사에서 프로그래머들이 사용할 수 있는 프로그래밍 언어의 종류가 어떤것이 있는지 확인하는 등 중복을 없애고 존재하고 있는 데이터를 확인하기 위해 많이 사용됩니다.
fruits = {‘apple’, ‘lemon’, ‘watermelon’, ‘apple’} print(type(fruits)) #
print(fruits) # {‘lemon’, ‘watermelon’, ‘apple’} 순서가 없으므로 출력이 매번 변경됩니다. # 빈 세트는 함수를 통해서만 생성할 수 있다. d = {} print(type(d)) # s = set() print(type(s)) # print(s) # set() 세트는 중괄호를 이용해서 초기화할 수 있습니다. 하지만… 뒤에서 알아볼 dictionary 타입도 중괄호를 사용하기 때문에 빈 세트를 생성할 때는 set함수를 꼭 사용해야합니다. 위 예제에서 볼 수 있듯이 fruits 세트에서 중복을 제거하고 순서도 매번 실행할 때 마다 다른 값을 얻는 것을 확인할 수 있습니다.
Set 내장 함수 제어
set도 mutable 데이터 구조입니다. 값을 변경할 수 있습니다.
fruits = {‘apple’, ‘lemon’, ‘watermelon’, ‘apple’} print(fruits) # {‘lemon’, ‘watermelon’, ‘apple’} 순서가 없으므로 출력이 매번 변경됩니다. # 세트에 추가하기 fruits.add(‘melon’) print(fruits) # {‘apple’, ‘melon’, ‘lemon’, ‘watermelon’} # 세트에 모든 엘러멘트 추가하기 fruits.update([‘grape’, ‘watermelon’, ‘mango’]) print(fruits) # {‘melon’, ‘apple’, ‘lemon’, ‘mango’, ‘grape’, ‘watermelon’} # 세트에서 제거하기(매개변수로 받은 값이 세트에 없으면 오류가 발생한다.) fruits.remove(‘grape’) print(fruits) # {‘apple’, ‘watermelon’, ‘lemon’, ‘mango’, ‘melon’} # fruits.remove(‘grape’) # KeyError: ‘grape’ # 세트에서 제거하기(매개변수로 받은 값이 세트에 있으면 삭제한다. 오류가 발생하지 않는다.) fruits.discard(‘watermelon’) print(fruits) # {‘lemon’, ‘melon’, ‘mango’, ‘apple’} fruits.discard(‘watermelon’) # 세트에서 무작위로 값을 반환하고 제거한다. print(fruits.pop()) # 무작위로 값이 나오기 때문에 어떤 값이 나올지 모른다. # 세트에서 모든 값을 제거한다. fruits.clear() print(fruits) # set()
함수들은 실습을 통해 확인한다.
세트의 집합 연산
Python의 세트는 연산기호들을 통해서 집합에 대한 연산이 가능합니다.
fruits1 = {‘apple’, ‘lemon’, ‘watermelon’, ‘apple’} fruits2 = {‘apple’, ‘lemon’} fruits3 = {‘apple’, ‘lemon’} fruits4 = {‘apple’, ‘grape’} “”” 비교 연산으로 크다 작다의 개념으로 이해하면 됩니다. subset 이하, 이상 –> 같은 경우를 포함 초과, 미만 –> 같은 경우는 미포함 “”” # fruits1이 fruits2의 상위집합인가? print(fruits1 >= fruits2) # True print(fruits1 > fruits2) # True # fruits1이 fruits2의 부분집합인가? print(fruits1 <= fruits2) # False print(fruits1 < fruits2) # False # fruits2가 fruits3의 상위 집합인가? print(fruits2 >= fruits3) # True # 같은 경우는 False print(fruits2 > fruits3) # False # 합집합 print(fruits2 | fruits4) # {‘grape’, ‘lemon’, ‘apple’} # 교집합 print(fruits2 & fruits4) # {‘apple’} # 차집합 print(fruits1 – fruits2) # {‘watermelon’} # 여집합 print(fruits1 ^ fruits4) # {‘grape’, ‘watermelon’, ‘lemon’}
실습을 통해 직접 확인해본다.
Dictionary(딕셔너리)
다른 언어에서의 Map이라는 오브젝트와 동일한 데이터 구조 입니다. key, value를 쌍으로 구성된 집합입니다. list나 tuple은 인덱스가 숫자의 형태로 되어 있는데 dictionary의 경우 인덱스를 문자형이나 숫자형처럼 immutable한 데이터 타입으로 되어 있습니다. 숫자보다는 문자형으로 key를 사용합니다.
d = { ‘red’: ‘apple’ ,’yellow’: ‘lemon’ ,’purple’: ‘grape’ ,’orange’: ‘mango’ } print(type(d)) #
중괄호를 이용해서 Dictionary를 선언해 줄 수 있고 세미콜론(:)를 기준으로 key:value 형태로 데이터를 저장할 수 있습니다.
Dictionary 읽기
d = { ‘name’: ‘tom’, ‘age’: 30, ‘items’: { ‘pockets’: 3, ‘baskets’: [ [ ‘grape’, ‘lemon’ ], [ ‘apple’, ‘watermelon’ ] ] }, 1: 25 } print(d[‘name’]) # tom print(d[‘items’][‘pockets’]) # 3 print(d[‘items’][‘baskets’][1]) # [‘apple’, ‘watermelon’] print(d[1]) # 25
dictionary는 key의 값만 mutable한 데이터 타입으로 지정해주면 됩니다. value로는 숫자형, 문자형과 같은 데이터 타입이나 list, set과 같은 데이터 구조가 들어갈수도 있습니다. dictionary의 key가 index의 역할을 해주기 때문에 list를 읽었던 방법처럼 대괄호를 이용해서 접근할 수 있습니다.
Dictionary 생성 예제
a = {‘name’: ‘jamong’, ‘age’: 30} b = dict(name=’jamong’, age=30) c = dict(zip([‘name’, ‘age’], [‘jamong’, 30])) d = dict([(‘name’, ‘jamong’), (‘age’, 30)]) e = dict({‘age’: 30}, name=’jamong’) print(a == b == c == d == e) # True
dict 함수를 이용해서 여러 방법으로 dictionary를 생성할 수 있습니다.
Dictionary 데이터 제어
d = {‘name’: ‘tom’} # dictionary 데이터 추가 d[‘age’] = 30 # {‘name’: ‘tom’, ‘age’: 30} print(d) # dictionary 데이터 삭제 del d[‘name’] print(d) # {‘age’: 30}
dictionary의 key값을 이용해서 직접 데이터를 추가할 수 있습니다.
del 키워드를 사용해서 dictionary 값을 삭제할 수 있습니다.
Dictionary 함수를 통한 데이터 제어
d = { ‘name’: ‘tom’, ‘age’: 30 } # dictionary에 key의 존재여부 확인 print(‘name’ in d) # True print(‘name’ not in d) # False # dictionary (key, value) 형식으로 데이터 추출 print(d.items()) # dict_items([(‘name’, ‘tom’), (‘age’, 30)]) # dictionary key 값들을 추출한다. print(d.keys()) # dict_keys([‘name’, ‘age’]) # dictionary value 값드을 추출한다. print(d.values()) # dict_values([‘tom’, 30]) # dictionary의 value를 key값으로부터 얻을 수 있다. # key가 없는 경우 default로 None을 반환하고 2번째 인자를 지정해주면 해당 값을 반환한다. print(d.get(‘name’)) # tome print(d.get(‘height’)) # None print(d.get(‘height’, 123)) # 123 # dictionary의 데이터를 수정한다. # 이미 존재하는 key이면 overwrite하고 없으면 추가한다. d.update({‘age’: 20}) print(d) # {‘name’: ‘tom’, ‘age’: 20} # key에 해당하는 값을 반환하고 dictionary에서 삭제한다. # key가 없으면 오류를 발생시킨다. # 2번째 인가자 지정되어 있으면 오류가 아닌 해당 값을 반환한다. # popitem 함수는 같은 기능이지만 값이 아닌 key:value 아이템을 반환한다. print(d.pop(‘age’)) # 20 print(d) # {‘name’: ‘tom’} print(d.pop(‘age’)) # KeyError: ‘age’ print(d.pop(‘age’, 123)) # 123 # dictionary 데이터 모두 삭제 d.clear() print(d) # {}
예제를 통해 확인한다.
dictionary vs list
list는 숫자형태로 인덱스가 부여되고 dictionary는 key 형태의 인덱스를 직접 설정해줍니다. dictionary의 경우 문자형태 뿐만 아니라 숫자형태로도 key를 지정해줄 수 있는데… 그럼 key값을 숫자형태로 사용한다면 어떤 데이터 구조를 사용해야할까요?
우선 성능적으로 봤을 때 데이터에 접근하는 속도는 dictionary보다는 list가 훨씬 빠릅니다. 사용하는 데이터가 순차적인 번호로 인덱싱되어서 사용할 수 있다면 list나 tuple을 사용하는 것을 권장드립니다.
정리
데이터 구조와 알고리즘이란? – 잔재미코딩
본 자료와 같이 IT 기술을 잘 정리하여, 온라인 강의로 제공하고 있습니다
체계적으로 전문가 레벨까지 익힐 수 있도록 온라인 강의 로드맵을 제공합니다
파이썬과 컴퓨터 사이언스(자료구조): 데이터 구조와 알고리즘이란? – 잔재미코딩.
- Source: www.fun-coding.org
- Views: 87923
- Publish date: 50 minute ago
- Downloads: 54868
- Likes: 1723
- Dislikes: 8
- Title Website: 데이터 구조와 알고리즘이란? – 잔재미코딩
- Description Website: 파이썬과 컴퓨터 사이언스(자료구조): 데이터 구조와 알고리즘이란? – 잔재미코딩.
서울대학교 자료구조 과제 수준을 알아보자
- Source: Youtube
- Views: 108751
- Date: 39 minute ago
- Download: 50779
- Likes: 6792
- Dislikes: 8
파이썬과 컴퓨터 사이언스(자료구조): 데이터 구조와 알고리즘이란?
본 자료와 같이 IT 기술을 잘 정리하여, 온라인 강의로 제공하고 있습니다
체계적으로 전문가 레벨까지 익힐 수 있도록 온라인 강의 로드맵을 제공합니다
쉽게 배우는 자료구조 with 파이썬 – 알라딘
16 thg 1, 2022 — 기본 자료구조와 알고리즘을 밀도 있게 풀어낸 기본서다. 기본 원리는 이해하기 쉽게 단계별로 차근차근 설명하면서도 구현을 위해 논리의 골격을 …
- Source: www.aladin.co.kr
- Views: 27276
- Publish date: 19 hours ago
- Downloads: 105685
- Likes: 6725
- Dislikes: 9
- Title Website: 쉽게 배우는 자료구조 with 파이썬 – 알라딘
- Description Website: 16 thg 1, 2022 — 기본 자료구조와 알고리즘을 밀도 있게 풀어낸 기본서다. 기본 원리는 이해하기 쉽게 단계별로 차근차근 설명하면서도 구현을 위해 논리의 골격을 …
Stacks and Queues Explained in 5 Minutes
- Source: Youtube
- Views: 70407
- Date: 55 minute ago
- Download: 56887
- Likes: 3753
- Dislikes: 8
[Python] 자료구조와 알고리즘 – velog
→ tuple형식으로 input, 숫자가 작을수록 우선순위가 높다. 운영체제에서 멀티 태스킹을 위한 프로세스 스케쥴링 방식을 구현하기 위해 많이 사용됨
노드 = 데이터값 + 포인터 포인터: 각 노드 안에서 이전이나 다음 노드와의 연결 정보를 가지고있는 공간
: 떨어진 곳에 존재하는 데이터를 화살표로 연결해 관리, 노드와 노드가 포인터로 연결된 형태
14 thg 10, 2021 — Array (배열) · 장점: 빠른 접근 가능 (첫 데이터의 위치에서 상대적인 위치로 데이터 접근 가능 (인덱스) · 단점: 데이터의 추가/삭제가 어려움 (크기가 …
- Source: velog.io
- Views: 8120
- Publish date: 9 minute ago
- Downloads: 60230
- Likes: 2904
- Dislikes: 7
- Title Website: [Python] 자료구조와 알고리즘 – velog
- Description Website: 14 thg 10, 2021 — Array (배열) · 장점: 빠른 접근 가능 (첫 데이터의 위치에서 상대적인 위치로 데이터 접근 가능 (인덱스) · 단점: 데이터의 추가/삭제가 어려움 (크기가 …
파이썬프로그래밍L0301 : 자료구조와 리스트 기초
- Source: Youtube
- Views: 88305
- Date: 22 hours ago
- Download: 13820
- Likes: 8344
- Dislikes: 4
[Python] 자료구조와 알고리즘
자료구조와 알고리즘
어떤 자료구조와 알고리즘을 쓰느냐에 따라 성능이 크게 달라질 수 있다.
Data Structure (자료구조)
: 컴퓨터 내의 데이터들을 효율적으로 저장하고 사용(관리)하는 방법들
코드 상에서 효율적으로 데이터를 처리하기 위해, 데이터 특성에 따라 구조화필요
→ 어떤 데이터 구조를 사용하느냐에 따라 코드 효율이 달라짐
대표적인 자료구조
: 배열, 스택, 큐, 링크드 리스트, 해쉬 테이블, 힙 등
Array (배열)
: 데이터를 나열하고 각 데이터를 인덱스에 대응하도록 구성한 데이터 구조
장점: 빠른 접근 가능 (첫 데이터의 위치에서 상대적인 위치로 데이터 접근 가능 (인덱스)
단점: 데이터의 추가/삭제가 어려움 (크기가 고정되어있음)
Queue (큐)
: FIFO(First In First Out), 선입선출 자료구조
Queue(): 선입선출
LifoQueue(): 스택 구조, 후입선출
PrioirtyQueue(): 우선순위가 높은 순으로 데이터 출력
→ tuple형식으로 input, 숫자가 작을수록 우선순위가 높다.
→ tuple형식으로 input, 숫자가 작을수록 우선순위가 높다. 운영체제에서 멀티 태스킹을 위한 프로세스 스케쥴링 방식을 구현하기 위해 많이 사용됨
Stack (스택)
: LIFO(Last In First Out), 후입선출 자료구조
한쪽 끝에서만 자료를 넣거나 뺄 수 있는 구조
장점: 데이터 처리 속도가 빠르다
단점: 저장공간의 낭비가 발생할 수 있다
(미리 최대 갯수만큼의 저장공간 확보 필요)
Linked List
: 떨어진 곳에 존재하는 데이터를 화살표로 연결해 관리, 노드와 노드가 포인터로 연결된 형태
노드: 데이터 저장 단위
노드 = 데이터값 + 포인터
노드 = 데이터값 + 포인터 포인터: 각 노드 안에서 이전이나 다음 노드와의 연결 정보를 가지고있는 공간
컴퓨터 내부의 프로세스 구조의 함수 동작 방식에 활용
Algorythm (알고리즘)
: 어떤 문제를 풀기 위한 절차/방법
어떤 문제에 대해 특정 ‘입력’을 넣으면 원하는 ‘출력’을 얻을 수 있도록 만드는 프로그래밍
시간 복잡도 / 공간 복잡도가 중요
시간복잡도
: 알고리즘을 위해 필요한 연산의 횟수 (알고리즘 실행 속도)
입력의 크기가 커질수록 반복문이 알고리즘의 수행 시간을 지배
공간복잡도
: 알고리즘을 위해 필요한 메모리의 양 (알고리즘이 사용하는 메모리 사이즈)
알고리즘 성능 표기법
Big O(빅-오) 표기법
주제에 대한 관련 정보 파이썬 자료 구조
Bing에서 파이썬 자료 구조 주제에 대한 최신 정보를 볼 수 있습니다.
주제에 대한 기사 보기를 마쳤습니다 파이썬 자료 구조. 이 기사가 유용했다면 공유하십시오. 매우 감사합니다. 사람들이 이 주제와 관련하여 자주 검색하는 키워드: 파이썬 자료 구조 파이썬 자료구조와 알고리즘 pdf, 파이썬 자료구조 책, 파이썬 자료구조 pdf, 파이썬 자료구조 강의, 파이썬 자료구조 책 추천, 파이썬 자료구조 종류, 파이썬 자료구조 라이브러리, 파이썬 자료구조 구현