본문 바로가기

Code-note

[기초문법]쓸만한 코드 LV.1-2 -python

last update : 2024.12.30

 

해당 내용을 Ctrl+F를 사용하여 검색

# 좌표평면에서 일정 범위 내의 정수 점의 개수를 구하는 방법
# 문자열/리스트에서 각 요소/문자의 개수를 세는 방법(Counter 객체 생성하기 )
# 두 리스트의 개수를 담은 객체를 생성하여 연산하는 방법(Counter 객체 연산)
# 에러가 났을 때의 실행 조건을 설정하는 방법
# 문자열의 모든 문자를 각각 리스트의 요소로 저장하는 방법
# 리스트의 요소를 중복없이 집합으로 나타내어 차 집합을 구하는 방법
# 두 집합의 교집합과 합집합을 구하는 방법: &, |
# 두가지 변수를 동시에 읽어와서 리스트에 순차적으로 저장하는 방법
# 두 배열을 같은 위치끼리 묶어서 하나의 반복문에서 읽어오는 방법
# 이차원 배열 행렬전환(전치행렬)1 : 문자열을 같은 인덱스 자리 값끼리 묶기 - zip
# 이차원 배열 행렬전환(전치행렬)2 : numpy.transpose 
# 2진수와 10진수를 서로 변환하는 방법
# 10진수 n을 k진법으로 변환하는 방법
# 반복문에서 값을 하나씩 생성하며 읽어오는 방법
# 함수의 리턴값이 존재하지 않을 때(빈 리스트) 실행되는 조건 추가
# n의 소수의 합을 구하는 방법1: n//2+1
# n의 소수의 합을 구하는 방법2: 에라토스테네스의 체 알고리즘
# 약수의 개수가 홀수 인 조건을 쉽게 확인하는 방법
# 약수의 개수를 시간 효율적으로 구하는 방법(n//2+1보다 좋음)
# 문자열이 모두 문자/숫자로만 이루어 졌는 지 간단하게 확인하는 방법
# 2차 행열의 덧셈 방법(같은 자리 요소끼리의 합)
# 자연수 n이 k의 몇 제곱수의 범위에 속하는 지 확인하는 방법 - 소수점 올림, 내림
# 소수점 자리수 2자리 까지만 출력(소수점 버림) : floor
# 배열 내의 숫자의 중복없이 가능한 모든 조합을 확인하기 위한 방법 : combinations
# 리스트의 요소로 가능한 모든 조합을 생성하는 방법: permutations
# 특정 패턴이 문자열 전체를 구성하는 지 확인(정규식) : re.fullmatch()
# 자연수를 2로 반복해서 나누면서  나누어 지지 않으면 1을 빼가며 2로 나누는 과정에서 1을 뺀 횟수를 세는 방법
# 오른쪽 정렬(rjust)과 왼쪽 정렬(ljust)을 하는 방법
# 데큐를 사용하여 효율성 좋게 리스트 최대/최솟값을 하나씩 빼와서 연산하는 방법
# 에러 조건과 정상 실행 조건을 설정한 코드 
# # 리스트의 앞 뒤 문자열을 비교하여 뒤의 문자가 앞의 문자로 시작하는 지를 확인

 

import math
def solution(k, d):
    answer = 0
    for x in range(0, d+1, k): # x축을 기준으로 
        max_y = int(math.sqrt(d*d-x*x)) # 거리 d를 넘지 않는 y의 최대값
        answer += max_y//k + 1 # x, y의 값이 k 단위 만큼 증가한다. + (x,0)점 포함
    return answer

# 좌표평면에서 일정 범위 내의 정수 점의 개수를 구하는 방법 : y**2 = d**2-x**2 (피타고라스 정리) ; O(n)

from collections import Counter
def solution(s):
    c = Counter(s.lower())
    return c['y'] == c['p']
# input: s = "pPoooyY"
# c = Counter({'y': 2, 'p': 1}) 
# 딕셔너리의 특성을 모두 가진다.

# 문자열/리스트에서 각 요소/문자의 개수를 세는 방법(Counter 객체 생성하기 ) : Counter(list or str)

# Counter 객체는 객체의 value의 더하기/빼기(연산)가 가능하다.
import collections
def solution(participant, completion):
    cnt = collections.Counter(participant) - collections.Counter(completion)
    for k,v in cnt.items():
        if v > 0: return k

# 두 리스트의 개수를 담은 객체를 생성하여 연산하는 방법(Counter 객체 연산)

# 프로그래머스 - 올바른 괄호 문제
def solution(s):
    stack = []
    for i in s:
        try: # 에러 발생 가능한 조건문
            if stack[-1]=='(' and i==')': stack.pop()
            else: stack.append(i)
        except: # 에러 발생 시 실행
            stack.append(i)
    return (stack == [])

# 에러가 났을 때의 실행 조건을 설정하는 방법 : try(에러가 날 수 있는 문장) - except(에러 발생시 실행) 구조

def solution(n):
    lst = sorted(list(str(n)), reverse = True)
    return int("".join(lst))
    
# str(n) = "118372"
# list(str(n)) = ['1', '1', '8', '3', '7', '2']

# 문자열의 모든 문자를 각각 리스트의 요소로 저장하는 방법: list(string)

def solution(numbers):
    all = set(list(range(10))) 
    # list(range(start, end, step)) : 연속된 숫자열 리스트 생성
    return (sum(list(all-set(numbers))))

# 리스트의 요소를 중복없이 집합으로 나타내어 차 집합을 구하는 방법 : set(list)

# 교집합, 합집합 구하기
str1 = ['fr', 'ra', 'an', 'nc', 'ce']
str2 = ['fr', 're', 'en', 'nc', 'ch']
gyo = set(str1) & set(str2)  # 교집합
hap = set(str1) | set(str2)  # 합집합
print(gyo) # {'fr', 'nc'}
print(hap) # {'nc', 'en', 'ra', 'an', 'fr', 'ch', 're', 'ce'}

#  두 집합의 교집합과 합집합을 구하는 방법: &, |

 

def solution(A,B):
    return (list(map(lambda a,b: (a,b), sorted(A), sorted(B,reverse=True))))
# A,B = [1, 4, 2], [5, 4, 4]
# output: [(1, 5), (2, 4), (4, 4)]

# 두가지 변수를 동시에 읽어와서 리스트에 순차적으로 저장하는 방법: lambda

def solution(A,B):
    return sum([a*b for a, b in zip(sorted(A),sorted(B,reverse=True))])

#  두 배열을 같은 위치끼리 묶어서 하나의 반복문에서 읽어오는 방법: zip()

from pprint import pprint
board = ["CCBDE", "AAADE", "AAABF", "CCBBF"]
board = list(map(list, zip(*board)))
# board = [''.join(i) for i in board]
pprint(board) 
#[['C', 'A', 'A', 'C'],
# ['C', 'A', 'A', 'C'],
# ['B', 'A', 'A', 'B'],
# ['D', 'D', 'B', 'B'],
# ['E', 'E', 'F', 'F']]

# 이차원 배열 행렬전환(전치행렬)1 : 문자열을 같은 인덱스 자리 값끼리 묶기 - zip으로 구현

import numpy as np
board = ["CCBDE", "AAADE", "AAABF", "CCBBF"]
board_lst = [list(i) for i in board]
board_trans = np.transpose(board_lst)
print(board_trans) 
#[['C' 'A' 'A' 'C']
# ['C' 'A' 'A' 'C']
# ['B' 'A' 'A' 'B']
# ['D' 'D' 'B' 'B']
# ['E' 'E' 'F' 'F']]

# 이차원 배열 행렬전환(전치행렬)2 : numpy.transpose 함수 사용

ten = 200
two = format(number, 'b') ; print(two) # 10 to 2
two_2 = bin(number) ; print(two_2[2:]) # 10 to 2
ten = int(two, 2) ; print(ten) # 2 to 10

# 2진수와 10진수를 서로 변환하는 방법: bin(int) or format(int, 'b'), int(int, k)

def n2k(n,k):
    tmp = ''
    while n:
        tmp += str(n % k)
        n = n // k
    return tmp[::-1]
print(n2k(45,2)) # 101101
print(n2k(45,3)) # 1200
print(n2k(45,10)) # 45

# 10진수 n을 k진법으로 변환하는 방법 (함수 구현)

def generator():
    a = 0
    while a<= 20: 
        yield a # 값을 하나씩 생성하는 방식으로 반환(메모리 효율성 좋음)
        a += 2      
print([i for i in generator()]) # 생성된 제너레이터 객체에서 생성된 값들을 하니씩 읽어올 수 있음
# next(gererator())를 사용하면 실행이 반복 될 때마다 값을 앞에부터 하나씩 생성하여 불러올 수 있음
# output : [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

# 반복문에서 값을 하나씩 생성하며 읽어오는 방법: yield 반환+ generator 객체 생성 

def solution(arr, divisor):
    answer = sorted([i for i in arr if i%divisor==0])
    return (answer if answer else [-1])

def solution(arr, divisor):
    return sorted([i for i in arr if i%divisor==0]) or [-1]

# 함수의 리턴값이 존재하지 않을 때(빈 리스트) 실행되는 조건 추가 : return A or B (A가 False면 B 리턴) 

def solution(n):
    return (sum([i for i in range(1, n//2+1) if n%i==0])+n)
    # n//2 부터의 값은 확인할 필요가 없다. n만 추가해 주고 종료

# n의 소수의 합을 구하는 방법1 : 1~n/2 까지의 값을 확인 + n 추가 ; O(n/2) / (n**0.5 - 제곱수 - 까지만 확인해도 됨)

def solution(n):
    num=set(range(2,n+1)) # n까지 모든 수가 소수라고 설정

    for i in range(2,n+1):
        if i in num: 
        	# i의 배수(2*i, 3*i ...)인 값을 집합에서 제거
            num-=set(range(2*i,n+1,i))
    return len(num) # 집합에 남아있는 수는 소수

# n의 소수의 합을 구하는 방법2: 에라토스테네스의 체 알고리즘 ; 2~n까지의 수 중 소수인 값만 집합에 남김 

def solution(left, right):
    answer = 0
    for i in range(left, right+1):
        if int(i**0.5)==i**0.5: answer -= i # 제곱수 확인
        else: answer += i
    return answer    
solution(13,17) # 43

# 약수의 개수가 홀수 인 조건을 쉽게 확인하는 방법: 제곱수(어떤 수를 두변 곱해 나오는 수)는 약수가 홀수개 이다. 

import math

def Cnt(num):
    cnt = 0
    # 약수는 항상 sqrt(num) 이하의 약수와 sqrt(num) 이상의 약수가 쌍을 이룸.
    # ex) 36 = (1x36),(6x6)
    for i in range(1, int(math.sqrt(num))+1):
        if num % i == 0:
            cnt +=1 
            if i != num//i: # 구하는 수가 약수의 제곱인 경우 배제 ex) 6x6
                cnt +=1
    return cnt

# 약수의 개수를 시간 효율적으로 구하는 방법(n//2+1보다 좋음) : 제곱수 까지만 확인 **소수 판별에도 사용가능! 

s1 = 'ssssaeetr'
s2 = '333334444s'
print(s1.isalpha()) # 모두 문자인지
print(s2.isdigit()) # 모두 숫자인지

# 문자열이 모두 문자/숫자로만 이루어 졌는 지 간단하게 확인하는 방법 : string.isalpha() / string.isdiigit()

A, B = [[1,2],[2,3]], [[3,4],[5,6]] # 길이가 같은 두 행렬
print(list(zip(A,B))) # [([1, 2], [3, 4]), ([2, 3], [5, 6])]
print(list(zip(*A,B))) # [(1, 2, [3, 4]), (2, 3, [5, 6])]
print(list(zip(A,*B))) # [([1, 2], 3, 5), ([2, 3], 4, 6)]
print(list(zip(*A,*B))) # [(1, 2, 3, 5), (2, 3, 4, 6)]
print([[a+b for a,b in zip(*x)] for x in zip(A, B)]) # [[4, 6], [7, 9]]
# 두 행열의 요소를 zip()으로 한번에 불러와, zip(*)로 풀어서 같은 인덱스의 값을 읽어온다. 
# 더한 값이 하나의 배열에 하나의 인덱스 요소로 들어갈 수 있도록 한다.

# 2차 행열의 덧셈 방법(같은 자리 요소끼리의 합) : zip(arr1, arr2), zip(*arr3) 

import math
def cross(n,k):
    up = math.ceil(math.log(n,k)) # 반올림
    dn = math.floor(math.log(n,k)) # 반내림
    if n==k**up: print(f'{n} == {k}^{up}')
    elif n==k**dn: print(f'{n} == {k}^{dn}')
    else: print(f"{k}**{dn} < {n} < {k}**{up}")
    return dn, up
cross(100, 2) # 2**6 < 100 < 2**7
cross(100, 10) # 2**6 < 100 < 2**7

# 자연수 n이 k의 몇 제곱수의 범위에 속하는 지 확인하는 방법 : math.floor(), math.ceil() - 소수점 

# 소수점 자리수 2자리까지만 출력(소수점 버림)
import math

number = 3.14566
floor_number = math.floor(number * 100) / 100
print(floor_number)  # 3.14

# 소수점 자리수 2자리 까지만 출력(소수점 버림) : floor

from itertools import combinations
n = [-2, 3, 0, 2, -5]
for i in combinations(n,3):
    if sum(i)==0: print(i) # 세 개의 수의 합이 0이되는 조합 찾기
# (-2, 0, 2)
# (3, 2, -5)

# 배열 내의 숫자의 중복없이 가능한 모든 조합을 확인하기 위한 방법: combinations(리스트, 조합 개수)

from itertools import permutations
def solution(expression):
    # 연산자 우선순위 경우의 수 생성
    operators = ['+', '-', '*']
    operator_permutations = permutations(operators, 3)
    print(list(operator_permutations))

# 리스트의 요소로 가능한 모든 조합을 생성하는 방법: permutations(리스트, 조합 개수)

import re
# 특정 패턴이 문자열 전체를 구성하면서 동일한 문자가 연달아 사용되지 않는지 확인
pattern = r"(aya|ye|woo|ma)+"  # 가능한 발음 패턴
word = "maayayema"
# 문자열 전체가 패턴으로 구성되고(fullmatch)
# 동일한 문자가 연달아 사용되지 않는지 확인(r"(패턴)\1")
if (re.fullmatch(pattern, word) 
    and not re.search(r"(aya|ye|woo|ma)\1", word)):
    print("매칭 성공")

# 특정 패턴이 문자열 전체를 구성하는 지 확인(정규식) : re.fullmatch()

def solution(n):
    n2 = format(n,'b') # 이진수
    return n2.count('1') # 이진수에서 1의 수 = 2로 나누어 지지 않는 횟수

# 자연수를 2로 반복해서 나누면서  나누어 지지 않으면 1을 빼가며 2로 나누는 과정에서 1을 뺀 횟수를 세는 방법

lst = ["10110", "110", "11000", "10"]
max_length = max(len(s) for s in lst)
rjust_lst = [s.rjust(max_length, '0') for s in lst] #['10110', '00110', '11000', '00010']
ljust_lst = [s.ljust(max_length, '0') for s in lst] #['10110', '11000', '11000', '10000']

# 오른쪽 정렬(rjust): 0을 왼쪽에 추가하여 문자열을 오른쪽으로 정렬합니다.
# 왼쪽 정렬(ljust): 0을 오른쪽에 추가하여 문자열을 왼쪽으로 정렬합니다.

from collections import deque
lst = sorted([70, 50, 80, 50], reverse=True)
q = deque(lst)
edge =q.popleft()+q.pop() # 80 + 50
print(edge) # 130

# 데큐를 사용하여 효율성 좋게 리스트 최대/최솟값을 하나씩 빼와서 연산하는 방법: deque.popleft() / deque.pop()

x_list = [0,10,20,30] ; print(x_list)
try: # 에러가 날 수도 있는 코드 실행
    idx = int(input('10을 나눌 숫자의 인덱스를 입력하시오 :'))
    y = 10/(x_list[idx])
except ZeroDivisionError: # 0으로 나눈 에러조건
    print("ZeroDivisionError; 0으로 나눌 수 없습니다.")
except IndexError: # 범위 밖의 인덱스가 입력된 에러조건
    print("IndexError; 잘못된 index가 입력되었습니다.") 
else: # try문이 성공했을 때 실행
    print(f"성공하였습니다. 결과 : {y}")
finally: # 실행 결과와 상관없이 실행
    print("코드 실행이 종료 되었습니다.")

# 에러 조건과 정상 실행 조건을 설정한 코드  : try-except-else-finally

def solution(phone_book):
    book = sorted(phone_book) # 비슷한 것끼리 인접하게 정렬되도록 정렬
    for i in range(len(book)-1):
        if book[i+1].startswith(book[i]): # 뒤의 문자(번호)가 앞의 문자(번호)로 시작하는 지
            return False
    return True

# 리스트의 앞 뒤 문자열을 비교하여 뒤의 문자가 앞의 문자로 시작하는 지를 확인: startswith()