파이썬 겉핥기

코승호딩·2022년 9월 25일
0
post-thumbnail

📌List

리스트는 순서가 있으며 중복을 허용하는 데이터들의 집합이다.

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b = range(10)

print(a) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 출력
print(b) # range(0, 9)가 출력이 된다.

이처럼 list와 range는 내부적으로 다른 것이지만 비슷한 용도로 사용이 된다.


for i in a:
  print(i, end=' - ') # end = 을 사용하면 개행 \n 대신 다른 문자 사용이 가능
print('//')
for i in b:
  print(i, end=' - ')
print('//')

for loop를 돌아보면 결과는 같지만 range를 쓰는 편이 효율 적이다.


print(len(a)) # 10출력
print(len(b)) # 10출력

len으로 크기를 구하면 결과는 동일하다


print(list(b)) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 출력

range를 list 형태로 꼭 나타내야 한다면 list 생성자를 이용한다.


📌Slicing

파이썬은 c++과는 달리 문자열의 일부를 잘라내서 사용할 수 있다.

words = [
  "flagrant",
  "lawmaker",
  "allow",
  "alumina",
  "concern",
  "kiosk",
  "incursion",
  "offhand",
  "especially",
  "wanton",
  "delectation",
  "hebraic",
  "inbred",
  "agitate", # 마지막 원소에 , 를 써도 된다 (trailing comma)
]

print('-- index 3 번째에 있는 것 --')
print(words[3])

print('-- index 3 번째 이후에 있는 것 --')
print(words[3:])

print('-- index 3 번째 직전까지 있는 것 --')
print(words[:3])

print('-- index 3 번째 이후, 4번째 직전까지 있는 것 --')
print(words[3:4])

word = "especially"
print(word[3:8], word[2:])
# slicing 은 문자열에 대해서도 적용된다

python 에서 범위를 지정할 때는 대부분 [inclusive, exclusive) 형태를 사용한다.
(거의)유일하게 random.randinit(10, 15) 의 경우만 [inclusive, inclusive] 형태이다.
random.randrange(10, 15) 를 쓰면 [10, 15) 가 되기도 한다.


📌Dictionary

Dictionary는 검색을 위한 키 값을 갖는 데이터들의 집합이다. key, value의 쌍으로 이뤄진다.
Dictionary는 빨리 찾는 것이 가장 중요한 구조이기 때문에 Key들이 정렬되어 있지 않다
파이썬 3.6 이후부터는 정렬이 가능하긴 하다.

twice = { 'momo' : 80, 'sana' : 90.5 } # 중괄호와 :을 사용하여 정의
print(twice['momo']) # key가 momo인 항목의 value 80을 출력한다.

keys = [ 'momo', 'dahyun', 'jihyo' ]
for key in keys:
	print('--key:', key)
    if key in twice:
    	value = twice[key]
    else:
    	value = '없다'
    print('--- Value:', value)    

세 개의 키 값에 대해서도 알아볼 수 있다.


words = [
  "flagrant",
  "lawmaker",
  "allow",
  "alumina",
  "foxglove",
  "fiche",
  "concern",
  "kiosk",
  "clean",
  "especially",
  "wanton",
  "addle",
  "agitate",
  "whinchat",
]

print('-- 각 글자별로 시작하는 단어가 몇개 있는제 세는 프로그램 --')
counts = dict() # Dictionary를 초기화
for word in words:
	first_ch = word[0]
    if not first_ch in counts: # Dictionary에 해당 key가 없으면
    	counts[first_ch] = 0 
    counts[first_ch] += 1

c++ 에서 사용하는 3항 연산자 a ? b : c를 파이썬에서는 b if a else c형태로 사용한다
ex) print("짝수" if num % 2 == 0 else "홀수")


from collections import defaultdict 
counts2 = defaultdict(int)
for word in words:
	first_ch = word[0]
    counts2[first_ch] += 1

이렇게 되면 존재하지 않는 key값이 들어올 경우 int() 즉 0 값이 들어 있었던 것으로 간주한다
매번 key가 있는지 찾아보는 것이 귀찮을 경우 defaultdict를 사용한다
default(???)로 생성된 것은 key가 존재하지 않는다면 ???()로 만든다


📌Tuple

Tuple은 순서가 있으며 중복을 허용하는 데이터들의 집합이다. 단, 데이터를 변경하는 것은 불가

t1 = 1, 2, 'hello', 3.5
t2 = (10, 10)

,로 연결하면 tuple이 되며 괄호를 안써도 되지만 보통 () 괄호를 사용한다


num,index,name,score = t1

arr = [100, 200]
first, last = arr

이처럼 tuple형태를 대입의 좌변에 사용할 수 있다
그리고 대입에서 배열을 우변, tuple을 좌변으로 놓을 수 있다.


xy1 = 123, 456 # xy1[1] += 10 같은 연산은 할 수 없다.

tuple은 읽기 전용 readonly이기 때문에 다음과 같은 연산이 불가능하다


📌Funcion

def func():
	print('This is a funcion')

func() # 'This is a funcion' 출력

함수를 사용하는 이유
인수 분해 : 함수를 두번 출력하고 싶으면 두번 호출하면 되고 인자를 넘어오는 부분만 다름
비슷한 것을 여러번 할거라면 공통적인 것을 함수로 정의하고 달라지는 것을 함수의 인자로 전달
동작의 추상화 : 프로그램을 짤 때, 함수 이름을 잘 짜놓으면 보는 사람이 편하다.


def func(arg):
	print(' = funcion with (', arg, ')')
    
func('hello')
func('world')

이와 같이 달라지는 것만 넘겨준다.


value = 123

def some():
	value = 456
    print('in some(), value = ', value) 
    
def other():
	print('in other(), value = ', value) 
   
some() # 456 출력 후 내부 value는 소멸
other() # 123 출력

다음과 같이 내부에서 선언한 변수는 함수 종료시 지역변수기 때문에 사라지지만 global변수인 외부 변수를 읽기만 하면 외부의 변수를 참조한다


def func():
	print(value)
    value = 10

func()

위와 같이 읽기만 한 함수를 쓰게 되면 오류가 생긴다.


def func():
	global value
	print(value)
    value += 20
    print(value)
    
func()

다음과 같이 global을 변수 앞에 선언하면 외부정의 변수를 읽고 쓸 수 있다.


def func(x, y):
	print('point = ', x, y)
    
func(10, 20) # 직접 여러 개로 전달

arg_tuple = 12, 23
func(*arg_tuple) # *을 붙인 이유

arg_list = [34, 45]
func(*arg_list)

함수는 평범히 여러 개로 매개 변수 전달이 가능하고 포인터를 붙인 이유는 만약 포인터를 안 붙이고 arg_tuple만 넘겨주게 되면 첫번째 인자로 tuple을 넘긴 것이 된다.


def func(name, age, score = 0, method = None, msg = ' '):
	if method == None:
    	method = 'the-default-method'
    print('name=', name, 'age=', age, 'I got:', score, method, f"[{msg}]")
    
func('hello', 20)
func('hello', 20, 4.5, 'get')
func('hello', 20, 'get')
func('hello', 20, method = 'get')

arg_dict = { 'name': 'KKY', 'score': 123, 'msg': 'Hello,world', 'age':30 }
func(**arg_dict) # dict 형태로 함수 인자로 전달 가능

다음과 같이 다양한 매개변수로 넘겨줘도 알아서 찰떡같이 알아 듣고 넣어준다.
별 두개는 dict을 넘겨줄 때 사용된다.


def func_list(*args):
	print('I got', len(args), 'arguments. first is', args[0])

func_list(10)
func_list(10, 20)
func_list(10, 20, 30)
func_list(10, 20, 30, 40)

def func_dict(**hash):
	print('Got the dictionary argument:', hash)

func_dict(name='john', age=20, score=4.5, msg='Hello,world')

다음과 같이 받는 쪽에서 list나 dict으로 받을 수 있다.


def func_two_return(a, b):
	sum = a + b
    mul = a * b
    return sum, mul
    
sum, mul = func_two_return(12, 5)

다음과 같이 리턴 타입을 두개이상의 값을 가진 투플로 리턴하는 것이 가능하다


📌Class

class Hello:
	pass
    
h = Hello()

파이썬에서는 줄을 비워 두면 안될 때 pass를 써야 한다.
그리고 함수 호출과 동일하게 타입 이름에 괄호를 열고 닫으면 해당 타입의 객체를 생성한다.


def func():
	return 'This is a string'
    
flags = [True, False, True]
for flag in flags:
	todo = Hello if flag else func
    obj = todo()
    print('flag 값은 :', flag, '이번에 얻은 것은 :', obj)

다음과 같이 함수 호출과 객체 생성이 동일한 문법 구조에 일어난다.


h1 = Hello()
h2 = Hello()

h1.name = 'David'
h2.age = 20

for obj in h1, h2
	for attr in 'name', 'age':
    	if hasattr(obj, attr):
        	print(f'객체{obj}는 속성{attr}을 가지고 있어요')

이 문장에서 for문을 해석해보면 우선 obj에 h1을 대입하고 이중 for문으로 name과 age를 attr에 차례로 대입하여 obj안에 attr이 있는지를 검사한다.
이처럼 파이썬은 class 객체에 임의의 속성을 런타임에 추가할 수 있다.


class World:
	def __init__(self): # c++의 this 대신 self를 사용한다. 멤버 함수는 첫번째 인자 self
		self.name = 'Unknown'
        self. age = 
        
w1 = World()
w2 = World()
w2.name = 'David'

클래스를 생성할 때 같이 넣어주면 생성될 때부터 속성을 가지고 있는다.


class HelloWorld:
	def __init__(self, name = 'UnKnown', age = 0): # 바로 초기화를 해줌(생성자 느낌)
    	self.name = name
        self.age = age
    def print(self):
    	print(f'name = {self.name}, age = {self.age}')

hw1 = HelloWorld('David', 20)
hw2 = HelloWorld('John', 23)
hw1.print()
hw2.print()

다음과 같이 생성자로 기본값을 설정하고 클래스 내에 함수를 정의할 수 있다.


class Worker:
	def __init__(self, name):
    	self.name = name
    def introduce(self):
    	print(f'name = {self.name}')

class Barista(Worker):
	def __init__(self, name):
    	super().__init__(name)
    def work(self):
    	print("열심히 커피 만들어요")
class Casher(Worker):
  def __init__(self, name):
    super().__init__(name)
  def work(self):
    print("주문 받고 돈받아요")
class Cleaner(Worker):
  def __init__(self, name, place):
    super().__init__(name)
    self.place = place
  def introduce(self):
    print(f'내이름은 {self.name}. {self.place} 를 청소하지.')
  def work(self):
    print("구석구석 깨끗이 청소해요")

workers = [
	Barista('David'),
    Cleaner('Dijkstra', 'Seungho'),
    Casher('John'),
    Cleaner('Bob', 'tables'),
    ]

for worker in workers:
	worker.introduce()
    worker.work()

다음처럼 파이썬은 상속 관계를 만들 수 있고 각자 다른 코드가 실행된다.


📌Format

파이썬도 format을 통해 스타일에 맞춰 출력을 할 수 있다.

students = [
 ( 'David', 22, (4.3 + 4.0 + 3.3) / 3 ),
 ( 'John Abdul', 25, (2.3 + 2.3 + 3.3) / 3 ),
 ( 'Chuck Norris', 124, (1.3 + 1.0 + 3.0) / 3 ),
 ( 'Karl Marx', 21, (3.3 + 2.0 + 4.3) / 3 ),
]

for st in students:
	name, age, score = st
   print(f'{name:^15} : {age:4} : {score:05.2f}')

'>'는 오른쪽 정렬 '<' 는 왼쪽 정렬, '^' 는 가운데 정렬이다

david = {'name':'David', 'age':22, 'score':3.866666}
print('%(name)-15s : %(age)4s : %(score)05.2f' % david)

이런 방식으로도 포맷팅이 가능하다


📌 Module

파이썬에는 매우 많은 내장 모듈이 존재한다.

import math
pt1, pt2 = [-150, -100], [150, 300]
distance = math.sqrt((pt1[0] - pt2[0])**2 + (pt1[1] - pt2[1])**2)

다음과 같이 math 모듈을 활용하여 sqrt를 사용할 수 있다.


angle_radian = math.atan2((pt1[1] - pt2[1]), (pt1[0] - pt2[0]))
angle_degree = 180 * angle_radian / math.pi

다음과 같이 역탄젠트로 두 점의 각도를 구할 수 있는데 atan2는 부호까지 신경써주기 때문에 atan2를 쓰면 된다.
대부분의 프로그램은 라디안 단위를 사용하기 때문에 degree로 변환해줄 필요가 있다.


dx = distance * math.cos(2 * angle_radian)
dy = distance * math.sin(2 * angle_radian)

두 점 사이의 거리를 알 때 각도만큼 회전한 좌표를 알기 위해서는 다음과 같은 cos, sin을 사용


dx = 회전의 중심 좌표 x + 반지름 r * sin(회전 각도θ / 360 * 2 * pi)
dy = 회전의 중심 좌표 y + 반지름 r * cos(회전 각도θ / 360 * 2 * pi)

다음의 식을 통해 회전 각도θ를 증가시켜 물체를 회전시킬 수 있다.


import pygame as pg
RED, GREEN, BLUE = (255, 0, 0), (0, 255, 0), (0, 0, 255)
BLACK, WHITE = (0, 0, 0), (255, 255, 255)
pg.init()
screen = pg.display.set_mode([900, 900])
font = pg.font.SysFont("arial", 16)
pg.display.set_caption('Test')
screen.fill(WHITE)
profile
코딩 초보 승호입니다.

0개의 댓글