<종합반 예습>

✏️01.입출력

게으른 함수들이 있다. 게으르다는 뜻은 계산한것을 바로 반환하지 않는다는 뜻이다.
일단 계산해서 담아두고 필요할 때 하나씩 꺼내서 쓸 수 있다. 오늘 내가 배운 게으른 함수는 바로바로 map()이다. map의 기본적은 형태는: map(함수, iterable객체)이다. 하나의 함수를 객체에 모두 적용시킬 수 있는 방법이다. 근데 얘는 바로 출력값이 나오지 않는다. 만약에 map을 그냥 print 해버리면, 객체를 담고 있는 주소가 나와버린다. 이 주소는 계산된 결과값이 저장되어있는 위치를 설명해준다고 한다. 컴퓨터의 세계는 알면 알수록 넓은 것 같다. 약간 뭐든지 다 될 것 같은 느낌.. 코드만 짠다면 뭐든 가능할 것 같다.
암튼,, 그래서 출력값을 볼려면 list()로 묶어주는 방법도 있고, for문을 통해서 하나씩 꺼내는 방법도 있다.

오늘 종합반 예습을 하면서, 오랜만에 예전에 배웠던것을 복습하니까 이게 뭐였더라 싶기도 하고, 계속 까먹는것 같다. 그래서 예습복습을 철저히 해야겠다. 오늘은 그래도 궁금한거 이것저것 시도해보면서, 하나씩 구글링하고 쳇지피티 사용해서 알아보고, 공부하고있다. 암튼 흥미로운 오늘. 정말 여러가지로 흥미롭다.

.split()은 문자열을 나눠서 리스트형태로 반환해주는 함수인데, 이거는 문자열에 대한 함수이기 때문에 문자열에 바로 붙여서 사용할 수 있다. 내가 실수했던 점은 map에다가 .split()을 붙였을 때이다. 그랬더니 바로 에러가 났다. map은 .split()함수를 사용할 수 없다고.
그래서 뭐지 싶었는데 내가 .split()이라는 함수를 모르는 것에서 오는 실수였다.

암튼 재밌다. 화이팅이다!!

그리고 print안에서 end=랑 sep=있는것 다시 상기!!
그리고 만약에 f스트링 사용하려면 함수를 넣을 때는 {}로 감싸주기!! 아니면 그냥 그 글자자체라 print되어버린다.

재밌다재밌어!!

✔️복습내용

분명 알았는데, 또 까먹은 것들 정리:

👉🏼산술연산자

산술연산자에서- 기본적인 나누기:/, 나눴을 때 몫만 구하기: //, 나눴을 때 나머지만 구하기: %,
몫과 나머지를 한번에 연산하기: divmod함수

  • divmod(): 두 개의 숫자를 인자로 받아, 첫번째 숫자를 두번째 숫자로 나눈 몫과 나머지를 튜플형태로 반환한다. 결국 divmod()함수가 하는 일은 다음과 같이 일반 연산자를 사용하여 나타낼 수 있다.-> divmod(x, y) = (x // y, x % y)

근데 / 이 아이랑 //이 아이랑 구분하는 것을 이렇게도 설명한다: /는 실수나누기 연산자, //는 정수나누기 연산자 라고. /이 아이를 사용하면 실수가 나오고, //이 아이를 사용하면 정수가 나온다. 이렇게 볼 수도 있다. 그리고 나눴을 때 나머지가 없는 경우엔 동일한 값을 반환한다. 단지 실수 형태로 나오느냐, 정수형태로 나오느냐가 다름.

if-elif-else구문: 가정법구문인데, elif를 사용하면 if를 여러개 사용할 수 있음.

❓여기서 나의 궁금증: elif를 꼭 사용해야 할까? 계속 if문을 써보면 어떨까? ->실험을 해봄.

num1 = float(input("첫번째 숫자를 입력하시오:"))
operator = input("연산자를 입력하세요(+,-,*,/):")
num2 = float(input("두번째 숫자를 입력하시오: "))

if operator == '+':
    result = num1 + num2
if operator == '-':
    result = num1 - num2
if operator == '*':
    result = num1 * num2
if operator == '/':
    if num2 != 0:
        result = num1 / num2
    else:
        result = "무한대 (0으로 나눌 수 없습니다)"
else:
    result = "유효한 연산자가 아닙니다."

print(f"결과: {result}")

이 코드의 결과와

num1 = float(input("첫번째 숫자를 입력하시오:"))
operator = input("연산자를 입력하세요(+,-,*,/):")
num2 = float(input("두번째 숫자를 입력하시오: "))

if operator == '+':
    result = num1 + num2
elif operator == '-':
    result = num1 - num2
elif operator == '*':
    result = num1 * num2
elif operator == '/':
    if num2 != 0:
        result = num1 / num2
    else:
        result = "무한대 (0으로 나눌 수 없습니다)"
else:
    result = "유효한 연산자가 아닙니다."

print(f"결과: {result}")

이 코드의 결과값은 같았음. 그럼 도대체 if와 elif의 차이점이 뭘까?

💡if와 elif의 차이점은: if는 위의 if조건이 충족되더라도 밑에 if문이 있으면 개별적으로 다 실행이 된다는 점이다. 하지만 if-elif는 위의 if절 또는 어느 elif절의 조건이 true로 충족되면(그 밑에 설사 elif절이 줄줄이 더 있다고 해도)그 코드에서 멈춘다. 더 이상 실행되지 않는다고 한다.

실무에서도 다들 if뒤의 더 다른 조건절들이 온다면 elif구문을 쓰니. 나도 그렇게 쓰도록!

👉input()함수

input()은 무조건 문자열을 반환한다. 그래서 숫자형을 받아서 그걸로 연산같은것을 하려면 꼭 int() 또는 float()로 숫자형으로 변환을 해주어야 한다.

‼️01-실습문제 틀린거

실습 문제 2 : 구분자와 줄 바꿈 바꿔보기(반복문 - for)

  1. range(1, 6)을 순회하며 숫자 1 ~ 5를 출력하는 코드를 작성하세요.
  2. 조건
    • print()한 번만 사용해 다섯 개 숫자를 출력할 것.
    • 숫자 사이 구분자는 콤마 , 대신 *세미콜론 ;으로 바꾼다.
    • 마지막에 줄 바꿈 대신 느낌표 !로 끝난다.
출력 예시 → 1;2;3;4;5!
  • 힌트: sepend 매개변수를 동시에 지정해 보세요.

이 문제에서 처음 푼 나의 코드

for i in range(1,6):
    print(sep=';',end='!')
   
   >>>!!!!!

음 이게 아니굼... 내가 여기서 틀린 이유는 뭘까,,,!!!

for i in range(1,6):
    print(i, end=';')
    
    >>>1;2;3;4;5;

print에 i를 안넣었음. 근데 끝에만 넣는것은 진자 모르겠음. 나 응용이 안되는듯..
일단 sep=에 대해 잘 모르는 듯.. 다시 위로 올라가서 복습! 해도 모르겠음.
어쨌든 sep=을 쓰려면, print에 여러개가 온 후에 sep=을 써야하는데,,

아 도저히 모르겠어서 결국 지피티의 힘을 빌렸다. 근데 좀 어이없음... 답이 너무 간단함..

print(*range(1, 6), sep=';', end='!')
>>>1;2;3;4;5!

🧱일단 여기서 내가 몰랐던 지식: 언패킹의 정의 및 사용위치.
언패킹(*)이란-> 리스트나 튜플, range 같은 묶음 자료형을 풀어서 전달해주는 것이다.
사용위치는 print()에서 사용이 가능하고, 함수 호출 시 인자 전달, 리스트/튜플을 병합할때에도 가능하다.

근데 이 문제에서 원하는 것은 for문을 사용해서 푸는 것이기 때문에,, 이것도 정답이 될 수가 없음..
정답코드

numbers = []
for i in range(1, 6):
    numbers.append(i)
print(*numbers, sep=';', end='!')

>>>1;2;3;4;5!

-> for문으로 range(1,6)을 돌면서 리스트 numbers에 값을 채움.
-> 마지막에 print()로 한 줄에 출력(‼️여기서 주의할 점: print는 꼭 줄을 for문과 동일한 선상으로 빼주어야 함. 만약에 numbes랑같은 줄에 있으면 반복할때마다 출력이 되어버림.)

🧱append: 리스트에 새로운 요소를 하나 추가할 때 사용하는 메서드.
기본문법: 리스트.append(추가할)
-> 리스트의 맨 뒤에 값을 하나 붙인다.
-> 원래 리스트 자체가 바뀌고, 반환값은 none이다.

enumerate() 함수

: enumerate는 파이선에서 반복문을 쓸 때 인덱스와 값을 함께 얻고 싶을 때 사용하는 함수이다. 이터러블한 데이터를 입력으로 받는다.
기본문법:

for i, name in enumerate(['body','foo','bar']):
     print(i, name)
     
     >>> 0 body
         1 foo
         2 bar

여기서 주의할 점은: 반복 할 객체를 두개 지정해주어야 한다는 점.-왜냐면 인덱스랑 값 같이 출력해야해서.

✏️02.변수

변수 이름 규칙

  1. 영문자, 숫자, 밑줄만 사용이 가능
  2. 숫자로 시작할 수 없음
  3. 대소문자 구분함
  4. 파이썬의 예약어는 사용 불가
for = 10  # 잘못된 예, 'for'는 예약어입니다.

예약어 목록 확인하기

import keyword

print(keyword.kwlist)

# 출력 결과
['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']

불린형 변수와 조건문

is_raining = False

if is_raining:
    print("우산을 가져가세요.")
else:
    print("우산이 필요 없습니다.")
# 출력: 우산이 필요 없습니다.

지역변수 vs 전역변수

지역변수는 함수 내에서 정의한 변수라서 함수내에서만 출력이 가능하고, 전역변수는 함수 밖에서 정의한 변수라서 어디에서든 출력이 가능하다.
+지역변수와 전역변수의 이름이 같을 때, 함수안에서 출력을 할 경우엔 가까이에 있는 지역변수를 먼저 참조하기 때문에 지역변수가 출력이 된다. 순서가 지역변수 참조-> 없으면 전역변수 참조. 이렇게 됨.

파이선에서 평균 구하기

이거 계속 헷갈려하는데-❗파이선에는 avg()라는 평균구하는 내장함수가 없음

len 함수

len()함수는 원소 개수를 알려준다.
리스트에 쓰이면 리스트의 항목 개수를 알려주고, 문자열에 쓰이면, 문자열의 문자 수를 알려준다.

  • 시퀀스 자료형(리스트, 문자열, 튜플 등) 과 컬렉션 타입(딕셔너리, 세트 등)에 사용이 가능하다
  • 정수나 실수는 여러개의 요소로 구성된 데이터가 아니라 하나의 값이기 때문에 len()으로 그 안에 포함된 항목 수를 셀수가 없음.

=> len() 함수는 " 이 안에 몇 개가 들어있나요?" 라고 묻는 것임.

✏️03.문자열

문자열은 '작은따옴표'나 "큰따옴표"로 생성이 가능함.

삼중 따옴표

삼중 따옴표 ''' ''' 또는 """ """ 를 사용하면 여러 줄로 이루어진 문자열 생성이 가능함.
->이 말은 원래는 여러줄로 이루어진 문자열 생성이 불가하단 말임.

인덱싱/슬라이싱

항상 헷갈리는 이 개념.. 오늘 확실히 정리!

  • 인덱싱: 문자열에서 인덱스를 사용해서 한 글자를 추출하는 것
    ex) text[2] → t

  • 슬라이싱: 문자열의 범위를 지정해서 추출하는 것
    ex) text[1:4] → yth
    [start:end:step]
    start : 부분 문자열의 시작 인덱스입니다. 이 인덱스의 문자는 부분 문자열에 포함됩니다. 시작 인덱스를 생략하면 기본값인 0이 지정
    end : 부분 문자열의 끝 인덱스입니다. 이 인덱스의 문자는 부분 문자열에 포함되지 않습니다. end가 생략되면 마지막까지 포함
    step : 현재 문자에서 step간격으로 문자를 추출합니다. step을 생략하면 기본값인 1로 설정

문자열 메서드

파이썬은 문자열을 조작하기 위한 다양한 내장 메서드를 제공한다.

(외운다는 느낌보다는 나중에 문제가 발생했을 때 “이런게 있었는데..” 하면서 해당 내용을 검색할 수 있다면 OKAY!)

대소문자 변환

  • upper(): 모든 문자를 대문자로 변환합니다.
  • lower(): 모든 문자를 소문자로 변환합니다.
  • capitalize(): 첫 번째 문자를 대문자로 변환합니다.
  • title(): 각 단어의 첫 문자를 대문자로 변환합니다.

문자열 검색 및 교체

  • find(sub): 부분 문자열 sub를 찾아 인덱스를 반환합니다. 없으면 -1을 반환합니다.
  • index(sub): 부분 문자열 sub를 찾아 인덱스를 반환합니다. 없으면 오류가 발생합니다.
  • replace(old, new): 문자열 내의 oldnew로 교체합니다. #replace가 문자열 메서드였음.

공백 제거

  • strip(): 문자열 양쪽의 공백을 제거합니다.
  • lstrip(): 문자열 왼쪽의 공백을 제거합니다.
  • rstrip(): 문자열 오른쪽의 공백을 제거합니다.

문자열 분할과 결합

‼️03-실습문제 틀린거

따옴표 사용 에러

print(f"replaced:{raw.replace('Python', "java")}")
-> 이게 에러가 났음.

에러가 난 이유는: 바깥에 큰따옴표가 있는데, 안에도 큰따옴표가 있어서 컴터가 헷갈려하는것임. 그래서 이럴때 쓰라고 작은따옴표, 큰따옴표 둘 다 가능하게 해놓은 것임. 안에는 하나로 통일하고 바깥에는 그 외의것으로 사용해야 함
그래서 에러 안나게하려면:

print(f"replaced:{raw.replace('Python', 'java')}")

이렇게 써야 함.


split(' ') vs split()

문제: 공백을 기준으로 분할하여 단어 리스트 word_list를 생성

나의 첫번째 풀이

word = raw.split(' ') #공백도 포함되어서 리스트 값에 출력됨.
print(word)

출력값에 공백도 포함되어서 출력됨.. 근데 공백 없이 출력해야했음.
도저히 모르겠어서 지피티 활용

word = raw.split() # 공백제거
print(word)

이렇게 하면 공백없이 문자만 리스트로 잘 출력됨.

여기서 한번 더 정리하는 split()개념: 문자열을 기준문자(구분자)를 기준으로 쪼개서 리스트로 만들어준다. 기준문자를 넣지 않으면 기본값은 공백이다. ->이부분이 이해가 안갔음. 기본값이 공백인데 왜 공백을 제거하고 문자만 리스트로 반환하는건지..?

split()에서 기준문자를 생략하면, 단순히 "공백 하나"가 기준이 아니라 모든 공백 문자(스페이스, 탭, 줄바꿈 등) 를 기준으로 연속된 공백도 무시하고, 비어 있는 항목은 제거한 채로 리스트를 만들어줘.

✏️04.리스트

리스트에서도 인덱싱과 슬라이싱이 가능한데,
여기서 슬라이싱에 대한 개념을 정리하고 넘어가야 될 것 같다.

🧱슬라이싱은 stop포인트값을 포함하지 않는다.

슬라이싱(Slicing)

슬라이싱의 기본적인 문법은 다음과 같습니다: (문자열 슬라이싱과 같습니다~!)

sequence[start:stop:step]
  • start: 슬라이싱을 시작할 인덱스 (포함).
  • stop: 슬라이싱을 종료할 인덱스 (불포함).
  • step: 요소를 건너뛰는 간격.

이때, start, stop, step은 모두 선택사항이며, 생략할 수 있습니다.

👉 파이썬에서 슬라이싱(slicing)은 리스트든 문자열이든 항상 stop 인덱스를 "포함하지 않는다"는 공통 규칙이 있어.

🧠 왜 stop이 불포함일까?
파이썬을 만든 귀도 반 로섬(Guido van Rossum) 은 이렇게 설명했어:

슬라이싱의 stop을 불포함으로 하면,
"범위 길이 = stop - start"가 항상 성립해서 코딩이 깔끔해진다.

즉,

python
복사
편집
s[a:b] → 길이 = b - a
이 수학적인 깔끔함이 유지돼!

📦 모든 시퀀스 자료형에 동일하게 적용돼
슬라이싱은 다음과 같은 시퀀스형 자료형에 전부 동일하게 적용돼:

문자열 (str)

리스트 (list)

튜플 (tuple)

범위 (range)

판다스 시리즈 / 데이터프레임 등도 슬라이싱 문법을 일부 공유

append() vs extend()

둘 다 리스트 내장함수, 즉 메서드이다. 그래서 쓰는 방법이 .append(), .extend()이렇게 됨.
두개의 다른점은 :

append는 추가하는 그대로를 리스트에 갖다붙여넣고, extend는 추가하는 이터러블한 객체를 하나씩 풀어서 리스트에 갖다붙여넣는다.

✅ append(item)
"그 원소 자체를 하나의 덩어리로 끝에 붙인다"

a = [1, 2, 3]
a.append([4, 5])
print(a)  # [1, 2, 3, [4, 5]]

a의 마지막 요소는 리스트 [4, 5] 자체

즉, 리스트 안에 리스트가 들어간 구조

✅ extend(iterable)
"그 원소가 이터러블이면, 그 안의 원소들을 하나하나 풀어서 붙인다"

a = [1, 2, 3]
a.extend([4, 5])
print(a)  # [1, 2, 3, 4, 5]

리스트 [4, 5] 안의 4, 5가 하나씩 추가됨

리스트가 한 단계 더 확장됨

리스트 컴프리헨션

comprehension: 이해, 포괄 이라는 뜻이다.
근데 어쨌든 리스트 컴프리헨션이라는 것은 (왜 컴프리헨션이라는 단어를 썼는지는 모르겠지만..?)
리스트 만드는 식을 더 간단하게 쓸 수 있는 방법이다. 처음엔 도대체 저게 뭐지 싶었는데 공부하고 나니 되게 흥미로운 방법이다.

# 기본 구조
new_list = [expression for item in iterable]

expression: 표현식을 넣는 자리이다.
item: 객체? 요소 넣는 자리
iterable: 이터러블한 것 넣는 자리
이게 보면 new_list라는 변수에다가 아예 리스트형식을 집어넣는다. 맨앞부터 맨뒤까지 리스트가 만들어져있는 것을 볼 수 있음. 그니까 이것은: 반복문을 통해 돌면서 표현식에 넣는것이다. 그리고 그걸 리스트로 만드는 것이라고 볼 수 있다.

리스트 컴프리헨션 사용

squares = [x**2 for x in range(1, 11) if x % 2 == 0]
print(squares)  
# 출력: [4, 16, 36, 64, 100]

중첩 리스트

아니 중첩리스트 있는건 알았는데 리스트중에서도 몇번째이것도 알았는데 그 리스트의 몇번째요소까지 뽑아낼수있는건 몰랐어서 적어놓는다.

matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

print(matrix[0])      # matrix의 0번 인덱스 - 출력: [1, 2, 3]
print(matrix[0][1])   # matrix의 0번 인덱스에서 1번 인덱스 값 - 출력: 2

내가 말하고 싶었던 건 print(matrix[0][1])이거다.

profile
청지기

0개의 댓글