python3 기초 3 - Data Structures

 

List

숫자, 문자, list 등 다양한 object으로 정의 가능하다

letters = ["a", "b", "c"]
matrix = [[0, 1], [2, 3]]

반복은 * 이용

zeros = [0] * 5
print(zeros)

## [0, 0, 0, 0, 0]

list 합치기도 가능, 숫자 + 문자 상관없음

letters = ["a", "b", "c"]
matrix = [[0, 1], [2, 3]]
zeros = [0] * 5
combined = zeros + matrix + letters
print(combined)

## [0, 0, 0, 0, 0, [0, 1], [2, 3], 'a', 'b', 'c']

list 함수 이용해서 iterable한 object을 넣어 list 정의가능

numbers = list(range(5))
text = list("Hello World")
print(numbers)
print(text)

## [0, 1, 2, 3, 4]
## ['H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd']

len으로 item 수 세기 가능

matrix = [[0, 1], [2, 3]]
print(len(matrix))

## 2


Accessing Items

index 하는 법은 string과 같다

letters = ["a", "b", "c", "d"]
print(letters[0])               ## a
print(letters[-1])              ## d
print(letters[1:3])             ## ['b', 'c']
print(letters[:3])              ## ['a', 'b', 'c']

짝수만 프린트하기

numbers = list(range(20))
print(numbers[2::2])           ## [2, 4, 6, 8, 10, 12, 14, 16, 18]
print(numbers[10:1:-2])        ## [10, 8, 6, 4, 2]

수정하기

letters = ["a", "b", "c", "d"]
letters[0] = "A"
print(letters)

## **['A', 'b', 'c', 'd']**


List Unpacking

list의 특정 item을 변수로 저장할수 있다.

아래 예처럼 쓰려면 list의 item수와 변수의 개수가 일치해야한다.

numbers = [1, 2, 3]
first, second, third = numbers
print(first, second, third)

## 1, 2, 3

*를 활용하면 packing이 가능

numbers = [1, 2, 3, 4, 5, 6, 7]
first, second, *other = numbers
print(first)                              ## 1
print(second)                             ## 2
print(other)                              ## [3, 4, 5, 6, 7]

중간에 쓸 수도 있다.

numbers = [1, 2, 3, 4, 5, 6, 7]
first, second, *other, last = numbers
print(other)                             ## [3, 4, 5, 6]
print(last)                              ## 7

여기서 *은 function 정의할때 parameter에서 packing하는 것과 동일한 동작을 한다

def multiply(*numbers):

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


Looping over Lists

list, tuple은 iterable 하다.

letters = ["a", "b", "c"]

for letter in letters:
    print(letter)

## a
## b
## c

enumerate는 loop에서 숫자세기 좋다. 결과는 index, value가 tuple로 저장된다

letters = ["a", "b", "c"]

for letter in enumerate(letters):
    print(letter)

## (0, 'a')
## (1, 'b')
## (2, 'c')

tuple이므로 index 가능하다

letters = ["a", "b", "c"]

for letter in enumerate(letters):
    print(letter[0], letter[1])

## 0 a
## 1 b
## 2 c

loop에서도 packing 이 가능하다

letters = ["a", "b", "c"]

for index, letter in enumerate(letters):
    print(index, letter)

## 0 a
## 1 b
## 2 c


Adding or Removing Items

list에 item을 추가하거나 제거할수 있다.



Add

letters = ["a", "b", "c"]

letters.append("d")
letters.insert(0, "-")
print(letters)

## ['-', 'a', 'b', 'c', 'd']


Remove

pop()은 마지막 item을 삭제한다. index 번호를 넣으면 해당 index의 item을 삭제한다

letters = ["a", "b", "c"]

letters.pop()
print(letters)

## ['a', 'b']

remove는 index를 모를 때 사용. 완전 일치하는 item만 삭제, 두개 이상 item이 일치하는 경우 index가 가장 빠른 item하나만 삭제

letters = ["a", "b", "c", "b"]

letters.remove("b")
print(letters)

## ['a', 'c', 'b']

del statement를 이용하면 특정 범위를 index하여 삭제가능

letters = ["a", "b", "c", "b"]

del letters[0:2]
print(letters)

## ['c', 'b']

모든 item 삭제는 clear method이용

letters = ["a", "b", "c", "b"]

letters.clear()
print(letters)

## []


Finding Items

특정문자의 index를 알고 싶다면 index method를 쓰면된다.

letters = ["a", "b", "c", "b"]

print(letters.index("b"))

존재하지 않는 item을 index로 검색하면 에러를 반환한다.

다른 언어의 경우 에러 대신 ‘-1’을 반환하는 경우도 있다.

에러를 보고 싶지 않으면 if 를 활용한다

letters = ["a", "b", "c", "b"]

if "d" in letters:
    print(letters.index("b"))

특정 item value의 숫자를 세고 싶으면 count method를 쓴다

완전히 일치하는 item만 센다

없으면 0 을 반환한다

letters = ["a", "b", "c", "bc"]

print(letters.count("b"))            ## 1


Sorting Lists

  • sort method를 쓰면 list를 정렬해서 저장한다.
  • default는 오름차순이다
  • reverse=True 를 쓰면 내림차순이다
numbers = [3, 20, 2, 9, 5]
numbers.sort()
print(numbers)                 ## [2, 3, 5, 9, 20]
numbers.sort(reverse=True)
print(numbers)                 ## [20, 9, 5, 3, 2]

sorted 함수를 쓰면 list를 저장하지는 않는다

numbers = [3, 20, 2, 9, 5]

print(sorted(numbers))          ## [2, 3, 5, 9, 20]
print(numbers)                  ## [3, 20, 2, 9, 5]

item이 tuple로 이루어져진 경우 sort가 어렵다

숫자 item을 반환하는 함수를 만들고 key로 호출할 수 있다.

key로 호출할때 함수를 호출(sort_item()) 한 것이 아니라 함수 이름만 reference로 입력했다.

items = [("Product1", 10), ("Product2", 9), ("Product3", 12)]

def sort_item(item):
    return item[1]

items.sort(key=sort_item)
print(items)

## [('Product2', 9), ('Product1', 10), ('Product3', 12)]


Lambda Functions

  • 위에서 sort_item 함수를 정의하는 것보다 lambda function을 이용하면 code가 심플해진다.
  • lambda 표현식 : lambda arguments : expression
  • argument는 복수 일수 있으나 expression은 하나다
items = [
    ("Product1", 10),
    ("Product2", 9),
    ("Product3", 12)
]

items.sort(key=lambda item: item[1])
print(items)


Map Function

다음과 같은 예시처럼 list에 있는 item 중 일부로 또다른 list를 만들때 map function을 활용할 수 있다.

items = [
    ("Product1", 10),
    ("Product2", 9),
    ("Product3", 12)
]

prices = []
for item in items:
    prices.append(item[1])

print(prices)

map function을 쓰면 map type object을 반환하고 이 type은 그대로 print 할 수없다. 그래서 list함수로 list type으로 변환.

items = [
    ("Product1", 10),
    ("Product2", 9),
    ("Product3", 12)
]

prices = list(map(lambda item: item[1], items))
print(prices)


Filter Function

  • list에서 특정 조건을 만족하는 item들 만으로 새로운 list를 만들때 사용
  • 결과로 filter object을 반환하므로 print하기 위해 list로 변환해준다.
items = [
    ("Product1", 10),
    ("Product2", 9),
    ("Product3", 12)
]

prices = list(filter(lambda item: item[1] >= 10, items))
print(prices)


List Comprehensions

다른 언어에서 찾기힘든 파이썬 기능

map, filter function을 대신할 수 있고 더 간편하다

items = [
    ("Product1", 10),
    ("Product2", 9),
    ("Product3", 12)
]

prices = list(map(lambda item: item[1], items))
prices = [item[1] for item in items]

prices = list(filter(lambda item: item[1] >= 10, items))
prices = [item for item in items if item[1] >= 10]


Zip Function

복수의 list item들을 같은 인덱스끼리 묶어 tuple을 구성하고 새 list를 만든다

list들의 item수가 다르면 가장 작은 수의 list가 기준이 된다.

list1 = [1, 2, 3]
list2 = [10, 20, 30, 40]

print(list(zip(list1, list2, 'abdsd')))

## [(1, 10, 'a'), (2, 20, 'b'), (3, 30, 'd')]


Tuple

  • 임의로 순서를 바꾸거나, 수정할 수 없다.
  • 그외에는 list와 비슷하다, 더할수 있고 곱할수 있다. index도 가능.
  • 변수 정의할때 ( ) 없이 , 만 포함해도 tuple로 인식한다
  • iterable 한 object을 tuple() function을 통해 tuple로 변환가능하다
point = 1,
print(type(point))

## <class 'tuple'>


Swapping Variables

  • 아래 처럼 변수 값을 서로 뒤바꿀 수 있다.
  • 아래에서 마지막 식 우변은 tuple을 정의한 것이다
  • 튜플에서 x, y로 unpacking 한것.
x = 10
y = 11

x, y = y, x


Arrays

  • list보다 빠르고 메모리를 적게 차지 한다.
  • 굉장히 큰 list일때 array를 사용. 그외에는 쓸일이 없다.
  • ‘i’는 typecode로 integer이다. typecode를 정했으면 다른 type의 item은 입력할 수 없다
  • list와 마찬가지로, append, insert, pop, remove등의 method 사용 가능.
  • list와 마찬가지로 index 가능
from array import array

numbers = array("i", [1, 2, 3])
numbers.append(40)
numbers.insert(4)
numbers.pop
numbers.remove
numbers[0]


Set

  • list에서 중복제거한 결과를 얻는다
  • 순서가 없는 object라서 index할수없다(numbers[0] 처럼)
numbers = [1, 1, 2, 3, 4]
uniques = set(numbers)
second = {1, 5}
#second =.add(5)
#second.remove(5)
#len(second)
print(uniques)               ## {1. 2. 3. 4}

print(numbers | second)      ## numbers와 second에 있는 모든 item 출력
print(numbers | second)      ## 양쪽 모두에 존재하는 item
print(numbers - csecond)     ## {2, 3, 4}
print(numbers ^ second)      ## {2, 3, 4, 5} 양쪽 공통은 제외하고 모두


Dictionaries

  • key와 value 쌍의 집합
  • key로는 immutable type만 가능
  • value는 모든 object 가능
  • dict함수로 생성가능
  • 순서가 없어서 숫자로 index는 안되지만, key로 value를 호출할 수 있다.
point = {"x": 1, "y": 2}
point = dict(x=1, y=2)
print(point["x"])
point["x"] = 10          ## 값 교체 가능
point["z"] = 20          ## 새로운 값 더하기 가능
print(point["a"]         ## KeyError 발생
if "a" in point:
		print(point["a"])    ## 에러 피하기 위해 check
print(point.get("a"))    ## a가 없으면 None을 기본으로 출력
print(point.get("a", 0)) ## a가 없으면 0을 출력
del point["x"]           ## x 삭제

loop

point = {"x": 1, "y": 2}
for key in point:
		print(key)            ## x 와 y를 출력한다(key를 출력)

for key in point:
		print(key, point[key])   ## key value 같이 출력

for x in point.items():
		print(x)                 ## key와 value를 tuple형태로 출력

for key, value in point.items():
		print(key, value)        ## key value 같이 출력


Dictionary Comprehensions

아래는 list comprehension

value = []
for x in range(5):
		values.append(x * 2)

[expression for item in items]

set과 dictionary에도 적용가능

아래는 set

values = {x * 2 for x in range(5)}
print(value)

## {0, 2, 4, 6, 8} # set

아래는 dictionary

values = {x: x * 2 for x in range(5)}
print(values)

## {0: 0, 1: 2, 2: 4, 3: 6, 4: 8}

아래와 결과는 같다

values = {}
for x in range(5):
    values[x] = x * 2
print(values)

## {0: 0, 1: 2, 2: 4, 3: 6, 4: 8}


Generator Expression

큰 사이즈의 데이터를 다룰때 사용

list처럼 iterable하고, 데이터를 저장하지않고 iterate 할때 마다 새 데이터를 생성한다

values = (x * 2 for x in range(10))    ## generator object
print(values)
for x in values:
		print(x)

getsizeof 를 이용하면 generator의 size를 구할 수 있다.

from sys import getsizeof
values = (x * 2 for x in range(100000))
print("gen:", getsizeof(values))           ## gen: 112
values = [x * 2 for x in range(100000)]
print("list:", getsizeof(values))          ## list: 800984

generator는 모든 데이터를 저장하지 않으므로 len()을 사용할 수 없다.



Unpacking Operator

*를 사용하면 unpacking 할 수 있다.

numbers = [1, 2, 3]
print(*numbers)         ## 1 2 3

iterable한 object들은 모두 unpacking이 가능하다

values1 = list(range(5))
values2 = [*range(5), *"Hello"]
print(values1)                     ## [0, 1, 2, 3, 4]
print(values2)                     ## [0, 1, 2, 3, 4, 'H', 'e', 'l', 'l', 'o']

list들을 unpack 할 수 도 있다.

first = [1, 2]
second = [3]
values = [*first, "a", *second, *"Hello"]
print(values)

## [1, 2, 'a', 3, 'H', 'e', 'l', 'l', 'o']

dictionary는 **를 사용한다.

같은 data가 있으면 뒤에 것이 적용된다.

first = {"x": 1}
second = {"x": 10, "y": 2}
combined = {**first, **second, "z": 1}
print(combined)

## {'x': 10, 'y': 2, 'z': 1}


Exercise

items()는 dictionary의 key와 value를 tuple로 묶고 전체를 list로 저장한다

sentence = "This is a common interview question"
# sentence에서 가장많이 나온 이니셜

char_frequency = {}
for char in sentence:
    if char in char_frequency:
        char_frequency[char] += 1
    else:
        char_frequency[char] = 1

char_frequescy_sorted = sorted(
    char_frequency.items(), key=lambda kv: kv[1], reverse=True)
print(char_frequescy_sorted[0])

댓글 쓰기

0 댓글