[Python] One-liners

DalKum·2024년 10월 24일

Python

목록 보기
1/1

1. 빠르게 훑는 파이썬 기본기

(1) 컨테이너 자료구조

is 키워드

y = x = 3

print(x is y)
# True

print([3] is [3])
# False

2 개의 list를 생성하면 (설령 두 list에 같은 값을 저장하더라도) 이 두 list는 메모리상에서 서로 다른 객체다. 그래서 한 list 객체를 변경해도 다른 list 객체는 영향을 받지 않는다.
list는 가변(mutable) ==== list 생성 이후에 변경 가능하기 때문이다.
하지만 정수값은 불변(immutable)이므로 한 변수를 변경한다고 해서 다른 모든 변수가 같이 변경되는 위험은 발생하지 않는다.

# 리스트: 가변
lst1 = [1, 2, 3]
lst2 = lst1
lst1[0] = 100  # lst1 값을 변경
print(lst1)  # [100, 2, 3]
print(lst2)  # [100, 2, 3]  -> lst1과 lst2는 같은 객체

# 정수: 불변
a = 5
b = a
a = 10  # a에 새로운 값을 대입 (기존 5는 유지)
print(a)  # 10
print(b)  # 5  -> a가 바뀌어도 b는 그대로
  • 메모리 관점:
    리스트는 같은 메모리 공간을 공유하기 때문에 둘 중 하나가 바뀌면 나머지도 바뀝니다.
    정수는 새로운 값을 할당할 때마다 새로운 메모리 공간을 사용하게 됩니다. 그래서 다른 변수에 영향을 주지 않아요.
  • 정리:
    가변(mutable): 객체의 값을 바꿀 수 있고, 변수가 그 객체를 공유하면 함께 변경됩니다. (리스트, 딕셔너리 등)
    불변(immutable): 값을 바꾸면 새로운 객체가 생성되고, 다른 변수에는 영향을 주지 않습니다. (정수, 문자열, 튜플 등)

멤버십

  • in 키워드 이용
print(42 in [2, 39, 42])
# True

print("21" in {"2", "39", "42"})
# True

print("list" in {"list": [1, 2, 3], "set": {1, 2, 3}})
# True

값 x가 컬렉션 y에 저장되어 있다면 x를 y의 멤버라고 함.

Set의 멤버십을 확인하는 것은 List의 멤버십을 확인하는 것보다 빠름. 값 x를 찾을 때까지 List에 저장된 모든 값을 훑어봐야 하기 때문임. 하지만 Set은 Dict와 비슷하게 구현되어 있어서, 파이썬은 값 x가 Set y에 저장되어 있는지 확인하기 위해 내부적으로 y[hash(x)]를 실행하고 리턴값이 None이 아닌지 확인함.

List와 Set Comprehension

  • [표현식 + 컨텍스트] 로 표현가능
    표현식은 파이썬이 list에 저장된 각 값에 어떤 작업을 수행할지 알려준다.
    컨텍스트는 파이썬이 list에서 어떤 값을 선택해야 하는지 알려준다. 컨텍스트는 여러 개의 for과 if 구문으로 구성할 수 있다.
# 원래 코드
squares = []

for i in range(10):
	squares.append(i**2)
    
print(squares)
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# 한 줄 코드
print([i**2 for i in range(10)])
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

iterable 객체들

타입순서 있음중복 허용Mutable인덱싱 가능특징
리스트OOOO순서가 있고, 값 변경 가능 (mutable)
튜플OOXO순서가 있지만, 값 변경 불가 (immutable)
셋 (Set)XXOX순서 없음, 중복 불가, 값 변경 가능
딕셔너리O키: X, 값: OO키로 접근 가능키는 immutable, 값은 mutable, 키-값 쌍, 순서 보장 (Python 3.7 이후)
문자열OOXO문자 시퀀스, 값 변경 불가 (immutable)
제너레이터X-XX값을 하나씩 생성, 메모리 효율적

(2) 흐름 제어

루프를 종료하는 기본적인 2가지 방법
1. 마지막에 False 값으로 평가되는 루프 조건 정의
2. 루프 본문 안에서 어떤 조건이 만족하면 break 키워드 사용

while True:
	break # 무한 반복하지 않는다
print("hello world")
# hello world

이 예제의 경우는 루프를 미리 종료한 후에 print 구문을 실행함.

파이썬 인터프리터가 루프를 미리 중단하지 않고도 루프의 특정 부분을 건너뛰게 할 수도 있음.
루프의 현재 실행을 중단하고 다음 루프 조건을 실행하는 continue 키워드를 사용하면 됨.

while True:
	continue
    print("43") # 이 코드는 절대 실행되지 않는다

이 코드는 print 구문을 한 번도 실행하지 않고 무한히 반복됨.
이렇게 절대 실행되지 않는 코드를 dead code라고 함.
그런 이유로 continue 구문(break 구문 포함)은 if-else를 이용한 특정 조건 내에서만 실행하는 것이 일반적임.

(3) 함수

람다 함수 (lambda function)

  • lambda <매개변수> : <리턴 표현식>
    하나 혹은 그 이상의 매개변수를 콤마로 구분해 지정 가능.
    콜론(:) 다음에는 매개변수를 사용해 어떤 동작을 수행하는 리턴 표현식을 작성. (파이썬 표현식 또는 다른 함수)
print((lambda x: x + 3)(3))
# 6

이 예제는 먼저 값 x를 받아 x + 3의 결과를 리턴하는 람다 함수를 정의함.
이 표현식의 결과는 다른 함수처럼 호출 가능한 함수 객체임.
함수의 동작으로 미루어 이 함수는 증분 함수(incrementor function)임.
이 증분 함수에 3이라는 매개변수를 전달해 호출하려면, print 함수 ㄴ에서 (3)과 같이 덧붙이면 됨. 그러면 결과로 정수값 6이 리턴됨.


2. 파이썬 200% 활용 비법

01. 리스트 컴프리헨션을 이용해 고액연봉자 찾기

  • [표현식 + 컨텍스트]
    [ ]은 리스트를 의미함.
    컨텍스트는 리스트에서 어떤 값을 선택할지 정의함. 하나에서 여러개의 중첩 for 루프를 이용해 정의된 여러 변수로 구성됨. 게다가 if 문 이용해 컨텍스트에 제한 둘수도 있음. (조건에 맞는 값만 새로운 리스트에 추가 됨.)
    표현식 context에서 정의된 변수를 전달받은 함수이거나 어떤 계산이든 수행 가능함. 외부의 함수까지 호출 가능.
    목표는 값을 새 리스트에 추가하기 전에 원하는대로 변경 가능.
# 1
print([x * 2 for x in range(3)])
# [0, 2, 4]
# 2
print([(x, y) for x in range(3) 
				for y in range(3)])

# [(0, 0), (0, 1), (0, 2),
#  (1, 0), (1, 1), (1, 2),
#  (2, 0), (2, 1), (2, 2)]
# 3
print([x ** 2 for x in range(10) 
				if x % 2 > 0])
# [1, 9, 25, 49, 81]
# 4
print(x.lower() for x in ['I', 'AM', 'NOT', 'SHOUTING'])
# ['i', 'am', 'not', 'shouting']
# 5
## 데이터
employees = {'Alice': 100000,
			 'Bob': 99000,
             'Carol': 122000,
             'Frank': 88000,
             'Eve': 93000}
             
## 한 줄 코드
top_earners = [(k,v) for k, v in employees.items()
						if v >= 100000]
                        
## 출력
print(top_earners)
# [('Alice', 100000), ('Carol', 122000)]

items()는 딕셔너리 객체의 메서드임. (key, value)의 쌍을 tuple로 묶어서 반환함.

02. 리스트 컴프리헨션을 활용해 정보 가치가 높은 단어 찾기

# 6
w = [[x for x in line.split() if len(x) > 3] 
		for line in text.split('\n')]
        
print(w)
  1. (바깥쪽의 리스트 컴프리헨션) 맨 뒤의 for문이 먼저 실행됨. split()은 문자열(str) 객체의 메서드로, text.split('\n') 코드에서는 개행문자를 기준으로 텍스트를 나눔. 각 줄을 요소로 하는 리스트를 반환함.
  2. (안쪽의 리스트 컴프리헨션의 표현식) line.split()에서 입력이 없으면, 개별 단어 단위로 쪼갬(공백 기준). 즉, 각 줄을 개별 단어로 분리해 냄.
  3. 변수 x에 차례로 전달되는 단어를 살펴보면서, 그 단어가 세 글자보다 길면(if 문) 리스트에 추가함.

03. 파일 읽기

# 7
print([line.strip() for line in open("@@@.py")])

strip()은 문자열(str)객체의 메서드로, 문자열의 양쪽 끝에서 공백이나 특정 문자를 제거하는 역할을 함.

profile
But many who are first will be last, and many who are last will be first. Mattityahu (Mat) 19:30

0개의 댓글