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

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

by RedBaDa 2023. 3. 7.
반응형

52. range()에서 사용할 수 있는 매개변수 step

for number in range(1, 10, 3):
    print(number, end=" ")
# 1 4 7

53. range()는 기본적으로 0부터 시작하므로 생략

그래서 0부터 시작할 거면 0을 그냥 생략하면 된다.

def range_with_zero(number):
    for i in range(0, number):
        print(i, end=' ')

def range_with_no_zero(number):
    for i in range(number):
        print(i, end=' ')

range_with_zero(3)  # 0 1 2
range_with_no_zero(3)  # 0 1 2

54. 자료형의 길이 len()는 0과 비교할 필요가 없음

길이가 0보다 크면 기본적으로 True이므로 0과 비교할 필요가 없다.

def get_element_with_comparison(my_list):
    if len(my_list) > 0:
        return my_list[0]

def get_first_element(my_list):
    if len(my_list):
        return my_list[0]

elements = [1, 2, 3, 4]
first_result = get_element_with_comparison(elements)
second_result = get_element_with_comparison(elements)

print(first_result == second_result)  # True

55. 동일한 scope 내에서 동일한 이름의 함수를 여러 개 정의할 수 있음

그러나 가장 마지막에 작성된 함수가 우선하기 때문에 마지막 항목만 호출된다.

def get_address():
    return "First address"

def get_address():
    return "Second address"

def get_address():
    return "Third address"

print(get_address())  # Third address

56. scope 밖에서 해당 속성에 접근하기

class Engineer:
    def __init__(self, name):
        self.name = name
        self.__starting_salary = 62000

dain = Engineer('Dain')
print(dain._Engineer__starting_salary)  # 62000

57. 특정 개체의 메모리 사용량 확인하기

import sys

print(sys.getsizeof("bitcoin"))  # 56

58. 함수를 정의할 때 매개변수의 개수 제한 없애기

“*”을 사용한다.

def get_sum(*arguments):
    result = 0
    for i in arguments:
        result += i
    return result

print(get_sum(1, 2, 3))  # 6
print(get_sum(1, 2, 3, 4, 5))  # 15
print(get_sum(1, 2, 3, 4, 5, 6, 7))  # 28

59. super() 또는 클래스 이름을 사용하여 부모클래스의 생성자를 호출하기

 

super()를 사용하여 부모클래스 이니셜라이저 호출하기

class Parent:
    def __init__(self, city, address):
        self.city = city
        self.address = address

class Child(Parent):
    def __init__(self, city, address, university):
        super().__init__(city, address)
        self.university = university

child = Child('Zürich', 'Rämistrasse 101', 'ETH Zürich')
print(child.university)  # ETH Zürich

부모클래스의 이름을 사용하여 이니셜라이저 호출하기

class Parent:
    def __init__(self, city, address):
        self.city = city
        self.address = address

class Child(Parent):
    def __init__(self, city, address, university):
        Parent.__init__(self, city, address)
        self.university = university

child = Child('Zürich', 'Rämistrasse 101', 'ETH Zürich')
print(child.university)  # ETH Zürich

__init__()  super()를 사용하는 부모 이니셜라이저에 대한 호출은 자식 클래스의 이니셜라이저 내에서만 사용할 수 있다.

60. 클래스 내에서 “+” 연산자 재정의하기

“+”는 __add__() 함수를 통해 재정의 할 수 있다.

class Expenses:
    def __init__(self, rent, groceries):
        self.rent = rent
        self.groceries = groceries

    def __add__(self, other):
        return Expenses(self.rent + other.rent,
                        self.groceries + other.groceries)


april_expenses = Expenses(1000, 200)
may_expenses = Expenses(1000, 300)

total_expenses = april_expenses + may_expenses
print(total_expenses.rent)  # 2000
print(total_expenses.groceries)  # 500

61. 클래스 내에서 “<“, “==” 등의 연산자 재정의하기

부등호 “<“는 __lt__() 를 재정의 하면 된다.

class Game:
    def __init__(self, score):
        self.score = score

    def __lt__(self, other):
        return self.score < other.score

first = Game(1)
second = Game(2)

print(first < second)  # True

“==”는 __eq__() 를 재정의하면 된다.

class Journey:
    def __init__(self, location, destination, duration):
        self.location = location
        self.destination = destination
        self.duration = duration

    def __eq__(self, other):
        return ((self.location == other.location) and
                (self.destination == other.destination) and
                (self.duration == other.duration))

first = Journey('Location A', 'Destination A', '30min')
second = Journey('Location B', 'Destination B', '30min')

print(first == second)

클래스 내에서 연산자를 재정의하기 위해서는 아래와 같은 함수를 다뤄주면 된다.

  • + : __add__()
  •  : __sub__()
  • * : __mul__()
  • / : __truediv__()
  • == : __eq__()
  • != : __ne__()
  • > : __gt__()
  • < : __lt__()
  • >= : __ge__()
  • <= : __le__()

62. 클래스 내에서 개체에 대한 print 표현형을 사용자 정의하기

클래스 내에서 __repr__()를 조작하면 print를 통해 출력했을 때 어떻게 표현할지 직접 정의할 수 있다.

class Rectangle:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def __repr__(self):
        return repr('Rectangle with area=' + str(self.a * self.b))

print(Rectangle(3, 4))  # 'Rectangle with area=12'

63. 문자열 대문자/소문자 바꾸기

문자열에 대해 swapcase()를 사용하면 대문자/소문자를 바꿔준다.

string = "This is just a sentence."
result = string.swapcase()
print(result)  # tHIS IS JUST A SENTENCE.

64. 문자열이 공백인지 확인하기

문자열에 대해 isspace()를 사용하면 모든 문자가 공백문자인지 확인한다.

string = "     "
result = string.isspace()
print(result)  # True

string = ""
result = string.isspace()
print(result)  # False

65. 문자열의 모든 문자가 알파벳 또는 숫자인지 확인하기

문자열에 대해 isalnum()을 사용하면 모든 문자가 알파벳과 숫자로만 이루어져있는지 확인한다.

name = "Password"
print(name.isalnum())  # True, because all characters are alphabets

name = "Secure Password "
print(name.isalnum())  # False, because it contains whitespaces

name = "S3cur3P4ssw0rd"
print(name.isalnum())  # True

name = "133"
print(name.isalnum())  # True, because all characters are numbers

66. 문자열의 모든 문자가 알파벳인지 확인하기

문자열에 대해 isalpha()를 사용하면 모든 문자가 알파벳으로만 이루어져있는지 확인한다.

string = "Name"
print(string.isalpha())  # True

string = "Firstname Lastname"
print(string.isalpha())  # False, because it contains whitespace

string = “P4ssw0rd”
print(string.isalpha())  # False, because it contains numbers

67. 문자열 양쪽에서 특정 문자 제거하기

문자열에 대해 strip([chars]), lstrip([chars]), rstrip([chars]) 과 같은 함수를 사용할 때 인자로 문자열을 넣어주면 해당 문자를 처음과 끝에서 찾아 제거한다. 그냥 strip은 양쪽에서, l은 왼쪽, r은 오른쪽에서 찾아 제거.

string = "This is a sentence with       "
print(string.rstrip())  # "This is a sentence with"

string = "this here is a sentence…..,,,,aaaaasd"
print(string.rstrip(".,dsa"))  # "this here is a sentence"

string = "ffffffffFirst"
print(string.lstrip("f"))  # First

68. 문자열이 숫자 형식인지 확인하기

문자열에 isdigit()을 사용하면 해당 문자열이 숫자 형식인지 확인한다.

string = "seven"
print(string.isdigit())  # False

string = "1337"
print(string.isdigit())  # True

string = "5a"
print(string.isdigit())  # False, because it contains the character 'a'

string = "2**5"
print(string.isdigit())  # False

69. 문자열이 중국어로 숫자인지 확인하기

문자열에 isnumeric()을 사용하면 숫자 표현에 해당하는 문자열인지 확인한다.

중국어뿐만 아니라 제곱근, 분수, 거듭제곱 등의 특수문자가 있더라도 isnumeric() 함수는 True를 반환한다.

# 42673 in Arabic numerals
string = "四二六七三"

print(string.isdigit())  # False
print(string.isnumeric())  # True

70. 문자열의 모든 단어 첫 글자가 대문자인지 확인하기

문자열에 istitle()을 사용하면 영어에서 제목을 표현할 때처럼 모든 단어 첫 글자가 문자열인지 확인한다.

string = "This is a sentence"
print(string.istitle())  # False

string = "10 Python Tips"
print(string.istitle())  # True

string = "How to Print A String in Python"
print(string.istitle())  # False, because of the first characters being lowercase in "to" and "in"

string = "PYTHON"
print(string.istitle())  # False. It's titlelized version is "Python"

71. 튜플에 음수 인덱스 사용 가능

numbers = (1, 2, 3, 4)

print(numbers[-1])  # 4
print(numbers[-4])  # 1

72. 튜플 내부에 리스트와 튜플 둘 다 담는 것도 가능

mixed_tuple = (("a"*10, 3, 4), ['first', 'second', 'third'])

print(mixed_tuple[1])  # ['first', 'second', 'third']
print(mixed_tuple[0])  # ('aaaaaaaaaa', 3, 4)

73. 리스트에 조건을 만족하는 요소가 있는지 카운트 하기

리스트에 count()를 사용하면 빠르게 해당 요소가 몇 개 있는지 확인할 수 있다.

names = ["Besim", "Albert", "Besim", "Fisnik", "Meriton"]

print(names.count("Besim"))  # 2

74. slice()를 사용하여 마지막 n개의 요소 슬라이싱하기

인덱싱을 하는 것과 다르다.

my_list = [1, 2, 3, 4, 5, 6]
slicing = slice(-3, None)

# Getting the last 3 elements from the list
print(my_list[slicing])  # [4, 5, 6]
# Getting only the third element starting from the right
print(my_list[-3])  # 4

string = "Data Science"
# start = 1, stop = None (don't stop anywhere), step = 1
# contains 1, 3 and 5 indices
slice_object = slice(5, None)
print(string[slice_object])   # Science

75. 튜플에 조건을 만족하는 요소가 있는지 카운트 하기

튜플에 count()를 사용하면 빠르게 해당 요소가 몇 개 있는지 확인할 수 있다. (73번과 같은 내용인데 굳이…?)

my_tuple = ('a', 1, 'f', 'a', 5, 'a')

print(my_tuple.count('a'))  # 3

76. 튜플에서 특정 요소의 인덱스 추출하기

튜플에 index()를 사용하면 빠르게 해당 요소가 몇 번째에 위치했는지 인덱스를 확인할 수 있다.

my_tuple = ('a', 1, 'f', 'a', 5, 'a')
print(my_tuple.index('f'))  #  2

77. 튜플에서 특정 간격으로 건너뛰어 요소 추출하기

my_tuple = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
print(my_tuple[::3])  # (1, 4, 7, 10)

78. 튜플에서 특정 인덱스부터 끝까지 요소 추출하기

my_tuple = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
print(my_tuple[3:])  # (4, 5, 6, 7, 8, 9, 10)

79. 리스트, 집합, 딕셔너리에서 모든 요소 제거하기

clear()를 사용하면 된다.

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

my_set = {1, 2, 3}
my_set.clear()
print(my_set)  # set()

my_dict = {"a": 1, "b": 2}
my_dict.clear()
print(my_dict)  # {}

80. 두 개의 집합 합치기 (합집합 구하기)

union()을 사용하면 된다.

first_set = {1, 4, 5, 6}
second_set = {1, 2, 3, 7}

print(first_set.union(second_set))  # {1, 2, 3, 4, 5, 6, 7}

아니면 두 번째 집합의 요소를 첫 번째 집합에 삽입하는 update()를 사용할 수도 있다.

first_set = {1, 4, 5, 6}
second_set = {1, 2, 3, 7}

first_set.update(second_set)
print(first_set)  # {1, 2, 3, 4, 5, 6, 7}

81. print문 안에 if 조건문 사용하기 

def is_positive(number):
    print("Positive" if number > 0 else "Negative")  # Positive

is_positive(-3) # Negative
is_positive(4)  # Positive

82. 하나의 if 안에서 모든 조건을 만족하는지 확인하기 

리스트 안에 검사할 조건을 다 넣어두고, all()을 사용하는 방식. 처음 알았다.

math_points = 51
biology_points = 78
physics_points = 56
history_points = 72

my_conditions = [
    math_points > 50, 
    biology_points > 50,
    physics_points > 50, 
    history_points > 50
    ]

if all(my_conditions):
    print("Congratulations! You have passed all of the exams.")
else:
    print("I am sorry, but it seems that you have to repeat at least one exam.")
    
# Congratulations! You have passed all of the exams.

83. 하나의 if 안에서 여러 조건 중 하나라도 만족하는지 확인하기

리스트 안에 검사할 조건을 다 넣어두고, any()를 사용하는 방식. 이것도 처음 알았다.

math_points = 41
biology_points = 58
physics_points = 36
history_points = 42

my_conditions = [
    math_points > 50, 
    biology_points > 50,
    physics_points > 50, 
    history_points > 50
    ]

if any(my_conditions):
    print("Congratulations! You have passed all of the exams.")
else:
    print("I am sorry, but it seems that you have to repeat at least one exam.")

# Congratulations! You have passed all of the exams.

84. 비어있지 않은 모든 문자열은 True

print(bool("Non empty"))  # True
print(bool(" "))  # True
print(bool(""))  # False

85. 비어있지 않은 모든 리스트, 튜플, 딕셔너리는 True

print(bool([]))  # False
print(bool(set([])))  # False
print(bool({}))  # False
print(bool({"a": 1}))  # True

86. None, False, 0은 False

print(bool(False))  # False
print(bool(None))  # False
print(bool(0))  # False
print(bool("False"))  # True

87. 함수 내에서는 전역 변수의 값을 변경할 수 없음

string = "string"

def do_nothing():
  string = "inside a method"

do_nothing()

print(string)  # string

만약 함수 내에서 전역 변수에 접근하고 싶다면 global을 사용해야 한다.

string = "string"

def do_nothing():
    global string
    string = "inside a method"

do_nothing()

print(string)  # inside a method

88. collections의 Counter를 사용해 문자열이나 리스트에서 요소 개수 카운트 하기 

Counter()는 정말 유용하다.

from collections import Counter

result = Counter("Banana")
print(result)  # Counter({'a': 3, 'n': 2, 'B': 1})

result = Counter([1, 2, 1, 3, 1, 4, 1, 5, 1, 6])
print(result)  # Counter({1: 5, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1})

89. collections의 Counter를 사용해 두 문자열이 애너그램인지 확인하기

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

Counter()를 사용해서 확인할 수 있다.

from collections import Counter

def check_if_anagram(first_string, second_string):
    first_string = first_string.lower()
    second_string = second_string.lower()
    return Counter(first_string) == Counter(second_string)


print(check_if_anagram('testinG', 'Testing'))  # True
print(check_if_anagram('Here', 'Rehe'))  # True
print(check_if_anagram('Know', 'Now'))  # False

sorted()를 사용해서 확인하는 방법도 있다.

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

90. itertools의 count를 사용해 리스트에서 요소 개수 카운트 하기

from itertools import count

my_vowels = ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']

current_counter = count()

string = "This is just a sentence."

for i in string:
    if i in my_vowels:
        print(f"Current vowel: {i}")
        print(f"Number of vowels found so far: {next(current_counter)}")

91. 문자열, 리스트의 요소를 빈도 순으로 정렬하기

기본적으로 collections.Counter()는 빈도에 따라 정렬해주진 않지만, most_common()을 사용해주면 쉽게 해결된다.

from collections import Counter

result = Counter([1, 2, 3, 2, 2, 2, 2])
print(result)  # Counter({2: 5, 1: 1, 3: 1})
print(result.most_common())  # [(2, 5), (1, 1), (3, 1)]

92. 리스트에서 가장 많은 요소 쉽게 찾기

max()와 set()을 조합하는 방법

my_list = ['1', 1, 0, 'a', 'b', 2, 'a', 'c', 'a']

print(max(set(my_list), key=my_list.count))  # a

93.  copy() 와 deepcopy()의 차이점

파이썬 공식 문서에는 이렇게 써있다.

  • A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original.
  • A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.

이게 copy()의 예시

first_list = [[1, 2, 3], ['a', 'b', 'c']]
second_list = first_list.copy()
first_list[0][2] = 831

print(first_list)  # [[1, 2, 831], ['a', 'b', 'c']]
print(second_list)  # [[1, 2, 831], ['a', 'b', 'c']]

이게 deepcopy()의 예시

import copy

first_list = [[1, 2, 3], ['a', 'b', 'c']]
second_list = copy.deepcopy(first_list)
first_list[0][2] = 831

print(first_list)  # [[1, 2, 831], ['a', 'b', 'c']]
print(second_list)  # [[1, 2, 3], ['a', 'b', 'c']]

94. 딕셔너리에 존재하지 않는 키 접근할 때 오류 방지 

딕셔너리에서 존재하지 않는 키에 접근하면 KeyError 오류가 발생한다.

my_dictonary = {"name": "Name", "surname": "Surname"}
print(my_dictonary["age"])  # KeyError: 'age'

collections의 defaultdict()를 사용하면 딕셔너리 키 에러 문제를 방지할 수 있다.

from collections import defaultdict

my_dictonary = defaultdict(str)
my_dictonary['name'] = "Name"
my_dictonary['surname'] = "Surname"

print(my_dictonary["age"]) 

95. 직접 나만의 반복자(iterator)를 만들기

class OddNumbers:
    def __iter__(self):
        self.a = 1
        return self

    def __next__(self):
        x = self.a
        self.a += 2
        return x


odd_numbers_object = OddNumbers()
iterator = iter(odd_numbers_object)

print(next(iterator))  # 1
print(next(iterator))  # 3
print(next(iterator))  # 5

96. 리스트에서 중복 항목 제거하기

set()을 활용한다.

my_set = set([1, 2, 1, 2, 3, 4, 5])
print(list(my_set))  # [1, 2, 3, 4, 5]

97. 모듈 위치 확인/출력하기

import torch

print(torch)  # <module 'torch' from '/Users/...'

98. “not in”을 사용해 리스트에 있는지 확인하기

odd_numbers = [1, 3, 5, 7, 9]
even_numbers = []

for i in range(9):
    if i not in odd_numbers:
        even_numbers.append(i)

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

99. sort()와 sorted()의 차이점

sort()는 원본 목록을 정렬하는 반면, sorted()는 새로운 정렬된 목록을 반환해준다.

groceries = ['milk', 'bread', 'tea']

new_groceries = sorted(groceries)
# new_groceries = ['bread', 'milk', 'tea']

print(new_groceries)

# groceries = ['milk', 'bread', 'tea']
print(groceries)

groceries.sort()

# groceries = ['bread', 'milk', 'tea']
print(groceries)

100. uuid 모듈을 사용해 고유 ID 생성하기 

UUID는 Universally Unique Identifier의 약자. 한국어로 범용 고유 식별자. 이 표준에 따라 ID를 부여하면 실제 사용상에서 중복될 가능성이 거의 없다고 인정되기 때문에 많이 사용되고 있다.

파이썬 내장 모듈 uuid가 있다.

import uuid

# Generate a UUID from a host ID, sequence number, and the current time
print(uuid.uuid1())  # 308490b6-afe4-11eb-95f7-0c4de9a0c5af

# Generate a random UUID
print(uuid.uuid4())  # 93bc700b-253e-4081-a358-24b60591076a
 
반응형