Python에서 None은 "값이 없다" 라는 의미를 가짐.
타언어 Null과 비슷함. is None은 None 객체를 정확하게 비교하는 방법으로, 두 객체가 동일한 객체인지 확인합니다. 반면, == None은 값 비교를 수행하는데, 객체 자체가 동일한지 여부가 아닌, 값이 None인지 여부를 확인합니다. is를 사용할 때는 객체의 ID를 비교하기 때문에 속도가 더 빠릅니다.
따라서 None을 체크할 때는 항상 is None을 사용하는 것이 좋습니다.
얕은 복사(Shallow Copy)
얕은 복사는 객체를 복사할 때, 객체의 "주소"만을 복사 새로운 객체가 만들어지지만, 그 객체를 참조하는 내부 데이터는 원본 객체와 동일. 밑의 예를 보면 리스트가 포함된 객체를 얕은 복사하면, 리스트의 참조값만 복사되어 새로운 리스트 객체가 아닌 원본 리스트의 내용이 공유됨.
import copy
original = [1, 2, [3, 4]]
shallow_copy = copy.copy(original)
shallow_copy[2][0] = 99 #shallow_copy의 내부 리스트 변경
print(original) # [1, 2, [99, 4]]
#두 리스트가 동일한 내부 객체를 참조하기에 original도 변경
print(shallow_copy) # [1, 2, [99, 4]]
깊은 복사(Deep Copy)
깊은 복사는 객체와 그 내부 객체들까지 모두 복사하여 새로운 객체를 만듭니다. 즉, 원본 객체와 복사된 객체가 각각 독립적인 데이터를 갖게 되어, 하나를 변경해도 다른 객체에는 영향을 미치지 않습니다.
import copy
original = [1, 2, [3, 4]]
deep_copy = copy.deepcopy(original)
deep_copy[2][0] = 99
print(original) # [1, 2, [3, 4]]
print(deep_copy) # [1, 2, [99, 4]]
import copy #deepcopy 함수 호출 위해서 copy 모듈 import
john = ['John', ('man','USA'),[175,23]]
tom = list(john) # 얕은 복사 = 껍데기만 새로 생성
chulsu = copy.deepcopy(john) # 깊은복사
john[2][1] +=1 #john의 내부 리스트 변경
print(john) # ['John', ('man', 'USA'), [175, 24]]
print(tom) # ['John', ('man', 'USA'), [175, 24]]
print(chulsu) # ['John', ('man', 'USA'), [175,23]] #변경되지 않음
리스트 컴프리헨션은 파이썬에서 새로운 리스트를 간단하고, 효율적으로 생성하는 방법
전통적인 방법으로는 for문을 사용하며 값을 하나씩 추가했지만, 리스트 컴프리헨션은 이를 한 줄로 간단하게 표현할 수 있게 해줍니다.
[<표현식> for <변수명> in <시퀀스>]
<표현식>은 시퀀스에서 각각의 항목에 대해 적용할 연산이고, <변수명>은 그 항목을 반복적으로 처리할 변수이며, <시퀀스>는 반복 가능한 데이터입니다.
squares = []
for i in range(10):
squares.append(i**2)
# 리스트 컴프리헨션을 이용한 방법
squares = [i**2 for i in range(10)]
리스트 컴프리헨션은 코드를 간결하게 하고 가독성을 높이는 데 매우 유용합니다. 또한 조건문을 추가하여 필터링도 할 수 있습니다.
# 0부터 9까지의 숫자 중 짝수만 제곱
squares = [i**2 for i in range(10) if i % 2 == 0]
number_even = [i for i in range(1,101) if i % 2 == 0]
multiples_3_or_5 = [i for i in range(1, 101) if i % 3 == 0 or i % 5 == 0]
powers_of_2 = [2**i for i in range(1, 11)]
set은 Python에서 제공하는 집합 자료형으로, 수학의 집합과 동일한 개념을 가집니다. set의 주요 특징은 다음과 같습니다:
특징
중복 허용 안 함: set은 중복된 값을 제거하기 위해 주로 사용됩니다.
순서 없음: set은 순서를 유지하지 않으므로 인덱싱과 슬라이싱이 불가능합니다.
중괄호 사용: {}로 정의되며, 비어 있는 집합은 set()으로 생성합니다.
my_set = {1, 2, 3, 4, 4, 5}
print(my_set) # {1, 2, 3, 4, 5} (중복 제거)
# 요소 추가 및 제거
my_set.add(6)
my_set.remove(1)
print(my_set) # {2, 3, 4, 5, 6}
# 집합 연산
set_a = {1, 2, 3}
set_b = {3, 4, 5}
print(set_a | set_b) # 합집합: {1, 2, 3, 4, 5}
print(set_a & set_b) # 교집합: {3}
print(set_a - set_b) # 차집합: {1, 2}
활용
import random
lotto = set() #로또가 set으로 인식 기존 lotto = ()일때는 중복제거가 필요하지만 얜 X
while len(lotto) < 6:
num = random.randint(1,45)
lotto.add(num)
# if num not in lotto: # set은 중복을 제거하기 때문에 중복제거함수를 빼도 됨
# lotto.append(num)
print(lotto)
두 사람이 게임을 진행한다. 이들의 이름을 키보드로 입력받으며 각 사람은 Person 클래스로 작성하라. 그러므로 프로그램에는 2개의 Person 객체가 생성되어야 한다. 두 사람은 번갈아 가면서 게임을 진행하는데 각 사람이 자기 차례에서 키를 입력하면, 3개의 난수가 발생되고 이 숫자가 모두 같으면 승자가 되고 게임이 끝난다. 난수의 범위를 너무 크게 잡으면 3개의 숫자가 일치하게 나올 가능성이 적기 때문에 숫자의 범위는 1~3까지로 한다.
2가지 방식
import random
class Person:
def __init__(self,name):
self.name = name
self.list_numbers = []
def set_list_numbers(self):
input(self.name + "의 차례입니다. <Enter> 키를 눌러주세요...")
#for i in range(3):
# self.list_numbers.append(random.randint(1,3))
self.list_numbers = [random.randint(1,3) for i in range(3)]
print(self.name + "의 숫자는 " + str(self.list_numbers) + "입니다.")
def get_list_numbers(self):
return self.list_numbers
while True:
try:
player1_name = input("첫 번째 사람의 이름을 입력하세요: ")
player2_name = input("두 번째 사람의 이름을 입력하세요: ")
break
except:
print("잘못된 입력입니다. 다시 입력하세요")
continue
player1 = Person(player1_name)
player2 = Person(player2_name)
tuple_player = ( player1, player2 )
is_stop = False
while True:
for player in tuple_player:
player.set_list_numbers()
numbers = player.get_list_numbers()
#if (numbers[0] == numbers[1]) and (numbers[1] == numbers[2]) and (numbers[0] == numbers[2]) :
# print(player.name + "가 이겼습니다!" + str(numbers))
# break
if len(set(player.get_list_numbers())) == 1:
print(player.name + "가 이겼습니다!" + str(player.get_list_numbers()))
is_stop = True
break
if is_stop:
break
import random
#Person 클래스 정의
class Person:
def __init__(self, name):
self.name = name
# 겜블링 게임 전체 로직을 처리하는 함수
def gambling_game():
# 두 사람의 이름 입력받기
name1 = input("첫 번째 플레이어 이름: ")
name2 = input("두 번째 플레이어 이름: ")
# 두 명의 Person 객체 생성
player1 = Person(name1)
player2 = Person(name2)
# 게임 진행
players = [player1, player2] # 객체를 리스트로 저장하여 게임에 순서도록 참여
turn = 0 #게임턴을 제어하기 위한 변수
print("\n=== 겜블링 게임 시작! ===")
while True: #승자가 나올때가지 무한 루프
current_player = players[turn % 2] # 번갈아가며 차례 지정
input(f"\n{current_player.name}님의 차례입니다. <Enter>를 눌러주세요.")
# turn % 2 == 0이면 player1, turn % 2 == 1 이면 player2
# 난수 3개 생성
numbers = [random.randint(1, 3) for _ in range(3)]
print(f"{current_player.name}님이 뽑은 숫자: {numbers}")
# 숫자가 모두 같으면 승리
if numbers[0] == numbers[1] == numbers[2]:
print(f"\n축하합니다! {current_player.name}님이 승리하였습니다! 🎉")
break
# 다음 차례로 변경
turn += 1
# 게임 실행
gambling_game()
id() 함수
id()는 객체의 고유한 메모리 주소(참조값)를 반환합니다.
Python에서 동일한 값을 가진 두 객체가 동일한 메모리 주소를 가질 수도 있고, 다를 수도있다.
예제
id()함수
a = [1, 2, 3]
b = a # b는 a와 같은 객체를 참조
print(id(a), id(b)) # 같은 메모리 주소 출력
a = [1, 2, 3]
b = [1, 2, 3]
print(id(a), id(b)) # 다른 메모리 주소 출력
== 연산자는 값이 같은지를 비교
==는 객체의 값(value)이 같은지를 비교합니다.
객체의 메모리 주소가 다르더라도 값이 같으면 True를 반환합니다.
a = [1, 2, 3]
b = [1, 2, 3] # 동일한 값을 가지지만 다른 메모리 주소
print(a == b) # True (값이 같음)
print(id(a) == id(b)) # False (메모리 주소가 다름)
# 날짜와 시간을 문자열로 출력
print("현재 시간 (문자열):", now.strftime("%Y-%m-%d %H:%M:%S"))
# 날짜와 시간을 생성
dt = datetime.datetime(2021, 9, 1, 12, 30, 45)
print("생성된 날짜와 시간:", dt)
# 날짜와 시간 연산
tomorrow = now + datetime.timedelta(days=1)
print("내일 날짜와 시간:", tomorrow)
# 날짜와 시간 비교
if now > dt:
print("현재 날짜와 시간이 생성된 날짜와 시간보다 뒤에 있습니다.")
else:
print("현재 날짜와 시간이 생성된 날짜와 시간보다 앞에 있습니다.")
4시부터 12 시 사이이면 => 굿모닝출력
12시부터 18 시 =>굿애프터눈 출력
18시부터 22 시 = > 굿 이브닝 출력
22시부터 04 시 => 굿나잇 출력
import datetime
def time_hi():
# 현재 시간 가져오기
current_time = datetime.datetime.now().hour
# 시간대에 따른 인사 출력
if 4 <= current_time < 12:
print("굿모닝")
elif 12 <= current_time < 18:
print("굿애프터눈")
elif 18 <= current_time < 22:
print("굿이브닝")
else:
print("굿나잇")
# 함수 실행
time_hi()
import datetime
# 현재 날짜와 시간 가져오기
now = datetime.datetime.now()
# 화면에 출력
print("현재 날짜와 시간:", now)
#출력예시
현재 날짜와 시간: 2025-01-14 02:57:21.791542
datetime 모듈의 now 함수의 리턴 값의 타입을 화면에 출력해보세요.
# datetime 모듈의 now 함수의 리턴 값의 타입을 화면에 출력해보세요.
import datetime
now = datetime.datetime.now()
print(now) # 출력 : 2025-01-13 17:28:40.949667
print(type(now)) # 출력 : <class 'datetime.datetime'>
import datetime
# 현재 날짜 가져오기
today = datetime.date.today() #datetime 뒤 date를 넣으면 일자가 나옴
# 5일, 4일, 3일, 2일, 1일 전 날짜 계산 및 출력
for i in range(1, 6):
days_ago = today - datetime.timedelta(days=i)
print(f"{i}일 전: {days_ago}")
#출력 예시
1일 전: 2025-01-13
2일 전: 2025-01-12
3일 전: 2025-01-11
4일 전: 2025-01-10
5일 전: 2025-01-09
현재시간을 얻어온 후 다음과 같은 포맷으로 시간을 출력해보세요. strftime 메서드를 사용하세요.
import datetime
# 현재 시간 가져오기
current_time = datetime.datetime.now()
# strftime을 사용하여 포맷된 시간 출력
formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S")
print("현재 시간:", formatted_time)
예제실행 결과
현재 시간: 2025-01-14 03:47:01
import time #sleep 함수 사용을 위해 time 모듈을 가져옴
from datetime import datetime #현재 시간을 가져오기 위해 datetime 모듈을 가져옴
while True:
# 현재 시간 출력
print(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
# 1초 대기
time.sleep(1)
세줄요약:
1.id 는 주소 == 값 비교 이다
2.얕은 복사는 껍데기 복사 , 깊은복사는 안에꺼 까지.
3. set 은 중복불가, 순서 없음 이다.