백엔드 파이썬 8일차 얕은복사, 깊은복사, 데이트타임

박재정·2025년 1월 14일

학습정보

목록 보기
8/29

1. None 도 데이타 타입중 하나이며, None 체크는 is None 이다.

Python에서 None은 "값이 없다" 라는 의미를 가짐.
타언어 Null과 비슷함. is None은 None 객체를 정확하게 비교하는 방법으로, 두 객체가 동일한 객체인지 확인합니다. 반면, == None은 값 비교를 수행하는데, 객체 자체가 동일한지 여부가 아닌, 값이 None인지 여부를 확인합니다. is를 사용할 때는 객체의 ID를 비교하기 때문에 속도가 더 빠릅니다.

따라서 None을 체크할 때는 항상 is None을 사용하는 것이 좋습니다.


2.얕은 복사와 깊은 복사를 예제를 들어 설명하시오.

얕은 복사(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]]

3. 아래의 결과 물이 똑같이 나오는 이유와 chulsu 는 deepcopy 가 되도록 하시오.

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]] #변경되지 않음

4. 리스트 컴프리 헨션이란?

리스트 컴프리헨션은 파이썬에서 새로운 리스트를 간단하고, 효율적으로 생성하는 방법
전통적인 방법으로는 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]

  1. 아래를 리스트 컴프리 헨션으로 표현해 보세요.
  • 구구단
  • 1부터 100까지의 숫자중 짝수만
number_even = [i for i in range(1,101) if i % 2 == 0]
  • 1부터 100까지의 숫자중 3의 배수 or 5의 배수
multiples_3_or_5 = [i for i in range(1, 101) if i % 3 == 0 or i % 5 == 0]
  • 1부터 10의 거듭제곱수
powers_of_2 = [2**i for i in range(1, 11)]

6. 데이터 타입중 set 에 대하여 설명하시오.

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}

활용

  • 데이터 중복 제거
  • 집합 연산(합집합, 교집합 등)
  • 효율적인 탐색 및 요소 검사

7. set 을 이용하여 로또를 짜시오.

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)

8.겜블링 게임을 만들어보자.

두 사람이 게임을 진행한다. 이들의 이름을 키보드로 입력받으며 각 사람은 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()

9. id 와 == 의 차이는?

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("현재 날짜와 시간이 생성된 날짜와 시간보다 앞에 있습니다.")

10.datetime 모듈을 할용하여, 현재시간을 체크 하고,

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()

11. datetime 모듈을 사용해서 현재 시간을 화면에 출력해보세요.

import datetime

# 현재 날짜와 시간 가져오기
now = datetime.datetime.now()

# 화면에 출력
print("현재 날짜와 시간:", now)

#출력예시 
현재 날짜와 시간: 2025-01-14 02:57:21.791542

12. 현재시간의 타입

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'> 

13 timedelta

datetime 모듈의 timedelta를 사용해서 오늘로부터 5일, 4일, 3일, 2일, 1일 전의 날짜를 화면에 출력해보세요.

  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

  

14.strftime

현재시간을 얻어온 후 다음과 같은 포맷으로 시간을 출력해보세요. 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
  
  1. sleep 함수
    time 모듈, datetime 모듈을 사용해서 1초에 한 번 현재 시간을 출력하는 코드를 작성하세요.

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 은 중복불가, 순서 없음 이다.

profile
파이썬, SQL 개발

0개의 댓글