본문 바로가기
개발/Python,파이썬

[Python/파이썬] 문법 좋은팁 100가지 -1

by RedBaDa 2023. 3. 7.
반응형

1. for-else 문

보통 프로그래밍 언어에서 ‘else’라고 하면 if와 함께 오는 경우가 대부분이다. 하지만 파이썬에서는 for 문과도 함께 쓸 수도 있다.

for문이 중간에 break 등으로 끊기지 않고 끝까지 수행 되었을 때 수행하는 코드를 담으면 된다. else는 for와 같은 수준으로 들여쓰기 해야 한다.

numbers = [2, 4, 1, 8, 6]

for number in numbers:
    if number % 2 == 1:
        print(number)
        break
else:
    print("No odd numbers")

위 예제는 리스트에 홀수가 있으면 반복문을 중단하는 코드. 홀수가 없으면 문자열이 출력되지만, 이 경우에는 홀수 1이 출력되고, 반복문이 중단된다.

for-else는 반복문이 중간에 break 되었는지 판별해야 하는 경우에 유용하다.

2. 변수명을 나열하여 리스트에서 요소들을 각각 가져오기

my_list = [1, 2, 3, 4, 5]
one, two, three, four, five = my_list

3. heapq를 사용하여 리스트에서 n개의 가장 큰/작은 요소를 가져오기

heapq는 파이썬 내장 모듈이다.

import heapq

scores = [51, 33, 64, 87, 91, 75, 15, 49, 33, 82]

print(heapq.nlargest(3, scores))  # [91, 87, 82]
print(heapq.nsmallest(5, scores))  # [15, 33, 33, 49, 51]

이걸 응용하면 딕셔너리에서도 key나 value를 기준으로 가장 큰, 가장 작은 값을 가져올 수 있다. 

scores = {"a": 51, "b": 33, "c": 64, "d": 87, "e": 91, "f": 75, "g": 15, "h": 49, "i": 33, "j": 82}

# sort by keys
print(heapq.nlargest(3, scores))  # ['j', 'i', 'h']
print(heapq.nsmallest(3, scores))  # ['a', 'b', 'c']

# sort by values
print(heapq.nlargest(3, scores.items(), key=lambda item: item[1]))  # [('e', 91), ('d', 87), ('j', 82)]
print(heapq.nsmallest(3, scores.items(), key=lambda item: item[1]))  # [('g', 15), ('b', 33), ('i', 33)]

4. 리스트에 “*” 사용하여 처리하기

“*”를 사용하여 리스트의 모든 요소를 추출할 수 있다.

my_list = [1, 2, 3, 4]
print(my_list)  # [1, 2, 3, 4]

print(*my_list)  # 1 2 3 4

이 방법은 리스트의 모든 요소를 메서드 인수로 전달하려는 상황에서 유용하다. (파이썬 함수 관련 글 참고)

def sum_of_elements(*arg):
    total = 0
    for i in arg:
        total += i

    return total


result = sum_of_elements(*[1, 2, 3, 4])
print(result)  # 10

5. 리스트 중간 있는 요소 가져오기

리스트에서 위치를 기준으로 앞이나, 뒤의 요소들을 잘라서 가져오는 신기한 방법.

“_”와 “*”를 사용한다.

_, *elements_in_the_middle, _ = [1, 2, 3, 4, 5, 6, 7, 8]
print(elements_in_the_middle)  # [2, 3, 4, 5, 6, 7]

_, _, *elements_in_the_middle, _,  _ = [1, 2, 3, 4, 5, 6, 7, 8]
print(elements_in_the_middle)  # [3, 4, 5, 6]

6. 한 줄에서 변수 여러개 할당

one, two, three, four = 1, 2, 3, 4

7. 리스트 컴프리헨션

리스트 컴프리헨션은 반복문을 한 줄로 처리할 수 있는 우아한 문법이다. 

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

even_numbers = [number for number in numbers if number % 2 == 0]

print(even_numbers)  # [2, 4, 6, 8]

리스트 컴프리헨션은 딕셔너리에서도 활용할 수 있다.

dictionary = {'first_element': 1, 'second_element': 2,
              'third_element': 3, 'fourth_element': 4}
odd_value_elements = {key: num for (key, num) in
                      dictionary.items() if num % 2 == 1}
print(odd_value_elements)  # {'first_element': 1, 'third_element': 3}

8. enum을 사용해 동일한 개념의 항목 반복하기

파이썬 공식문서 enum 설명

An Enum is a set of symbolic names bound to unique values. They are similar to global variables, but they offer a more useful repr(), grouping, type-safety, and a few other features.

from enum import Enum

class Status(Enum):
    NO_STATUS = -1
    NOT_STARTED = 0
    IN_PROGRESS = 1
    COMPLETED = 2

print(Status.IN_PROGRESS.name)  # IN_PROGRESS
print(Status.COMPLETED.value)  # 2

9. 연산자 * 활용하여 문자열 반복하기

string = "Abc"

print(string * 5)  # AbcAbcAbcAbcAbc

10. 숫자 3개 한 줄에서 비교하기

파이썬에서는 1 < x and x < 10 과 같은 비교를 한 줄로 처리할 수 있다.

x = 3
print(1 < x < 10)   # True

11. “|”를 사용하여 딕셔너리 병합하기 

파이썬 3.9부터 사용 가능한 문법.

first_dictionary = {'name': 'Fatos', 'location': 'Munich'}
second_dictionary = {'name': 'Fatos', 'surname': 'Morina', 'location': 'Bavaria, Munich'}

result = first_dictionary | second_dictionary
print(result)  
# {'name': 'Fatos', 'location': 'Bavaria, Munich', 'surname': 'Morina'}

12. 튜플에서 특정 요소의 인덱스 찾기

books = ('Atomic habits', 'Ego is the enemy', 'Outliers', 'Mastery')

print(books.index('Mastery'))   # 3

13. 문자열 형식의 리스트를 진짜 리스트로 변환하기

이렇게 리스트처럼 생긴 문자열을 “[1,2,3]” 진짜 리스트 [1,2,3]로 바꾸고 싶을 때… 생각보다 간단하지 않다.

물론 복잡한 정규식을 쓸 수도 있겠지만, ast 모듈에서 literal_eval 메서드를 사용하면 편하게 처리할 수 있다.

import ast

def string_to_list(string):
    return ast.literal_eval(string)

string = "[[1, 2, 3],[4, 5, 6]]"
my_list = string_to_list(string)
print(my_list)  # [[1, 2, 3], [4, 5, 6]]

14. 매개변수 이름을 활용하여 사소한 실수 줄이기

아래와 같이 subtract라는 함수를 만들어서 사용하는 데, 함수 안에 넣어줄 인수의 순서가 바뀌면 괜히 실수가 날 수 있다.

def subtract(a, b):
    return a - b

print((subtract(1, 3)))  # -2
print((subtract(3, 1)))  # 2

아래와 같이 매개변수 이름을 정확히 적어서 실수를 줄이자.

def subtract(a, b):
    return a - b


print((subtract(a=1, b=3)))  # -2
print((subtract(b=3, a=1)))  # -2

15. print 한 줄로 처리하기

print(1, 2, 3, "a", "z", "this is here", "here is something else")

16. print 여러 줄로 처리하더라도 한 줄에 출력되도록 (end)

end 파라미터를 사용하면 된다.

print("Hello", end="")
print("World")  # HelloWorld
print("Hello", end=" ")
print("World")  # Hello World
print('words',   'with', 'commas', 'in', 'between', sep=', ')
# words, with, commas, in, between

17. print 여러 개 출력할 때 사용자 정의 구분자 (sep)

sep 파라미터를 사용하면 더 예쁘게 출력할 수 있다.

print("29", "01", "2022", sep="/")  # 29/01/2022
print("name", "domain.com", sep="@")  # name@domain.com

18. 파이썬 변수명 맨 앞에 숫자는 올 수 없음

four_letters = “abcd” # this works
4_letters = “abcd” # this doesn’t work

19. 파이썬 변수명 맨 앞에 연산자가 올 수 없음

+variable = “abcd”  # this doesn’t work

20. 숫자 맨 앞 자리는 0이 될 수 없음

number = 0110 # this doesn't work

만약 문자열로 “0110” 같은 형식의 숫자를 만들고 싶다면 zfill 메서드를 활용하면 된다.

21. 언더스코어 “_”는 변수명 어디에도 사용할 수 있음

a______b = "abcd"  # this works
_a_b_c_d = "abcd"  # this also works

만약 문자열로 “0110” 같은 형식의 숫자를 만들고 싶다면 zfill 메서드를 활용하면 된다.

22. 자리수가 큰 숫자는 언더스코어 “_”를 사용하여 읽기 편하게 처리하기

숫자 사이에 언더스코어 “_” 1개가 들어오는 건 무시된다. (자리수 구분, 가독성을 위해 자유롭게 사용할 수 있다는 뜻)

print(1_000_000_000)  # 1000000000
print(1_234_567)  # 1234567

a = 1_000_000
b = 3_000
print(a + b)  # 1003000

23. 리스트 순서 뒤집기

my_list = ['a', 'b', 'c', 'd']

my_list.reverse()

print(my_list)  # ['d', 'c', 'b', 'a']

24. 문자열 건너뛰어 슬라이싱

my_string = "This is just a sentence"
print(my_string[0:5])  # This

# Take N steps forward
print(my_string[0:10:1])  # This is ju
print(my_string[0:10:2])  # Ti sj
print(my_string[0:10:3])  # Tssu

25. 문자열 순서 뒤집어서 슬라이싱

my_string = "This is just a sentence"
print(my_string[10:0:-1])  # suj si sih

# Take N steps forward
print(my_string[10:0:-1])  # suj si sih
print(my_string[10:0:-2])  # sjs i
print(my_string[10:0:-3])  # s  h

26. 슬라이싱 할 때 시작/끝 인덱스는 생략 가능

my_string = "This is just a sentence"
print(my_string[4:])  # is just a sentence

print(my_string[:3])  # Thi

27. 나누기 후 소수점 이하 버리기

print(3/2)  # 1.5
print(3//2)  # 1

28. “==” 와 “is” 의 차이

“==”는 이 두 개체가 가진 값이 일치하는지 비교하는 반면, “is”는 두 변수가 메모리의 동일한 객체를 가리키는지 확인한다.

first_list = [1, 2, 3]
second_list = [1, 2, 3]

# ==는 값이 같은지 확인
print(first_list == second_list)  # True

# is는 메모리 내의 동일한 객체를 가리키는지 확인
print(first_list is second_list)  
# False

third_list = first_list

print(third_list is first_list)  
# True

실제로 변수의 id를 확인해보면 first_list와 third_list는 동일한 ID를 갖고 있지만, second_list의 id는 다르다는 걸 확인할 수 있다.

print(id(first_list))
print(id(second_list))
print(id(third_list))

29. 딕셔너리 쉽게 병합하기 

dictionary_one = {"a": 1, "b": 2}
dictionary_two = {"c": 3, "d": 4}

merged = {**dictionary_one, **dictionary_two}

print(merged)  # {'a': 1, 'b': 2, 'c': 3, 'd': 4}

30. 부등호 연산자를 사용하여 문자열 비교하기

문자열에 부등호를 사용하면, 해당 문자열을 ascii 숫자로 변환해서 맨 앞의 문자부터 비교한다.

first = "abc"
second = "def"
print(first < second)  # True
second = "ab"
print(first < second)  # False

아스키코드표를 따르면, 혹은 ord함수를 이용하면 이렇게 몇 번째 유니코드 정수 값을 구할 수 있다. (39번 참고)

print(ord('a'))  # 97
print(ord('z'))  # 122

31. 문자열이 특정 문자로 시작하는지 확인하기

인덱싱 하지 않고 startswith로 처리하는 방법.

my_string = "abcdef"
print(my_string.startswith("b"))  # False

32. id()를 사용하여 변수의 고유 ID 찾기

print(id(1))  # 4325776624
print(id(2))  # 4325776656
print(id("string"))  # 4327978288

33. 정수, 실수, 문자열, 불리언, 튜플은 수정 불가(immutable)

정수, 부동소수점, 문자열, 부울, 튜플처럼 수정 불가(immutable)한 객체에 변수를 할당하면 이 변수는 메모리의 객체를 가리킨다.

그래서 만약 해당 변수에 다른 값을 할당하는 경우 원래의 객체는 여전히 메모리에 있지만 이를 가리키는 변수는 손실된다.

number = 1
print(id(number))  # 4325215472
print(id(1))  # 4325215472

number = 3
print(id(number))  # 4325215536
print(id(1))  # 4325215472

34. 문자열과 튜플은 수정 불가 (immutable)

바로 위에서 언급한 내용이지만 너무나 중요한 내용이기 때문에 다시 한 번 강조한다…?

name = "Fatos"
print(id(name))  # 4422282544
name = "fatos"
print(id(name))  # 4422346608

my_tuple = (1, 2, 3, 4)
print(id(my_tuple))  # 4499290128
my_tuple = ('a', 'b')
print(id(my_tuple))  # 4498867584

35. 리스트, 집합, 딕셔너리는 수정 가능(mutable)

이는 바인딩된 객체를 잃지 않고도 해당 변수를 변경할 수 있음을 의미한다.

cities = ["Munich", "Zurich", "London"]
print(id(cities))  # 4482699712
cities.append("Berlin")
print(id(cities))  # 4482699712

my_set = {1, 2, 3, 4}
print(id(my_set))  # 4352726176
my_set.add(5)
print(id(my_set))  # 4352726176

36. set을 수정 불가(immutable)하도록 변경하기

frozenset을 사용하면 immutable하도록 바꿀 수 있다.

my_set = frozenset(['a', 'b', 'c', 'd'])
my_set.add("a")    # AttributeError: 'frozenset' object has no attribute 'add'

37. if-elif 블록 끝에 else는 생략 가능

그러나 “elif”는 “if” 없이는 단독으로 쓰일 수 없다.

def check_number(number):
    if number > 0:
        return "Positive"
    elif number == 0:
        return "Zero"

    return "Negative"


print(check_number(1))  # Positive

38. sorted()를 사용하여 2개의 문자열이 어구전철인지 확인

어구전철(語句轉綴) 또는 애너그램(anagram)은 단어나 문장을 구성하고 있는 문자의 순서를 바꾼 거다.

구성하는 문자가 순서 상관 없이 일치하는지 확인하는 방법.

def check_if_anagram(first_word, second_word):
    first_word = first_word.lower()
    second_word = second_word.lower()
    return sorted(first_word) == sorted(second_word)
print(check_if_anagram("testinG", "Testing"))  # True
print(check_if_anagram("Here", "Rehe"))  # True
print(check_if_anagram("Know", "Now"))  # False

39. 문자에 해당하는 유니코드 값 얻기

ord는 해당 문자에 해당하는 유니코드 정수를 반환한다.

def check_if_anagram(first_word, second_word):
    first_word = first_word.lower()
    second_word = second_word.lower()
    return sorted(first_word) == sorted(second_word)
print(check_if_anagram("testinG", "Testing"))  # True
print(check_if_anagram("Here", "Rehe"))  # True
print(check_if_anagram("Know", "Now"))  # False

40. 딕셔너리 key만 가져오기

dictionary = {"a": 1, "b": 2, "c": 3}

keys = dictionary.keys()

print(list(keys))  # ['a', 'b', 'c']

41. 딕셔너리 value만 가져오기

dictionary = {"a": 1, "b": 2, "c": 3}

values = dictionary.values()

print(list(values))  # [1, 2, 3]

42. 딕셔너리에서 key, value 바꿔치기

리스트 컴프리헨션을 사용하면 간단히 처리할 수 있다.

dictionary = {"a": 1, "b": 2, "c": 3}

reversed_dictionary = {j: i for i, j in dictionary.items()}

print(reversed)  # {1: 'a', 2: 'b', 3: 'c'}

43. boolean 값을 숫자 1 또는 0으로 변환하기

print(int(True))  # 0
print(int(False))  # 0

print(float(True))  # 1.0
print(float(False))  # 0.0

44. boolean 값을 산술 연산에 사용하기

True는 1, False는 0이니까…

x = 10
y = 12
result = (x - False)/(y * True)
print(result)  # 0.8333333333333334

45. 모든 자료형은 boolean으로 표현 가능

print(bool(3))  # True
print(bool(.0))  # False

print(bool([1,2,3]))  # True
print(bool([]))  # False

print(bool("string"))  # True
print(bool(""))  # False
print(bool(" "))  # True

46. 복소수, 2진수/8진수/16진수 표현하기

복소수 변환은 complex() 함수를 사용한다.

print(complex(10, 2))  # (10+2j)

이 외에도 bin() , oct(), hex() 함수를 사용하면 숫자를 각각 2진수, 8진수, 16진수 형태의 문자열로 변환할 수 있다.

print(bin(11))  # 0b1011
print(oct(11))  # 0o13
print(hex(11))  # 0xb

파이썬에서는 기본적으로 10진수 형태로 숫자를 표현하기 때문에 다른 진수의 형태로 숫자를 표현하려면 다음과 같이 숫자 앞에 접두어를 붙여준다.

  • 2진수: 0b
  • 8진수: 0o
  • 16진수: 0x

47. 리스트 맨 앞에 요소 추가하기

리스트에 append()를 사용하면 맨 마지막에 해당 값를 추가한다. 만약 원하는 위치에 요소를 추가하고 싶다면 insert()를 사용하면 된다. (인덱스, 삽입할 요소 순으로 작성)

my_list = [3, 4, 5]

my_list.append(6)
my_list.insert(0, 2)
print(my_list)  # [2, 3, 4, 5, 6]

48. lambda 함수는 반드시 한 줄로 작성

lambda 함수는 한 줄로만 작성해야 한다.

여러 줄로 작성하면 SyntaxError 에러가 날 거다.

comparison = lambda x: if x > 3:
                    print("x > 3")
                else:
                    print("x is not greater than 3")

49. lambda 함수의 조건문에는 반드시 “else”를 포함하기

lambda 함수에 if 조건문을 이런 식으로 작성하면 SyntaxError 에러가 난다. (람다 자체의 문제가 아니라 조건문의 특성이다.)

comparison = lambda x: "x > 3" if x > 3

 

50. filter()를 사용하여 새로운 객체 돌려받기 

filter()는 lambda 함수와 조합하여 사용할 수 있다.

my_list = [1, 2, 3, 4]

odd = filter(lambda x: x % 2 == 1, my_list)

print(list(odd))   # [1, 3]
print(my_list)  # [1, 2, 3, 4]

51. map()을 사용하여 새로운 객체 돌려받기

my_list = [1, 2, 3, 4]

squared = map(lambda x: x ** 2, my_list)

print(list(squared))   # [1, 4, 9, 16]
print(my_list)  # [1, 2, 3, 4]

 

반응형