74. 파이썬 표준 라이브러리 operator.itemgetter operator.attrgetter

74. 파이썬 표준 라이브러리 operator.itemgetter operator.attrgetter

지난 포스팅에서는 functools.reduce() 를 사용해서 리스트 요소의 누적값과 최대값, 최소값을 구하는 코드를 알아봤습니다.
이번 포스팅에서는 operator.itemgetter 에 대해 공부해 보도록 하겠습니다.

파이썬 표준 라이브러리

operator.itemgetter

operator.itemgetter 라이브러리는 보통 sorted 같은 함수의 key 매개변수에 적용하여 여러가지 기준으로 정렬을 할 수 있게 도와 주는 모듈입니다.

튜플 정렬

아래 처럼 학생들의 이름과 나이, 성적 같은 정보를 저장한 students 리스트가 있다고 가정해 보겠습니다.

Python
#  students_list.py
students = [
    ("mickle", 25, 'A'),
    ("david", 22, 'C'),
    ("jone", 31, 'C'),
]

students 리스트에는 3개의 튜플이 있고 각 튜플은 이름, 나이, 성적에 해당하는 알파벳 의 순서대로 데이터가 만들어져 있습니다.
이 리스트를 나이 순으로 어떻게 정렬하면 좋을까요?
이 질문은 아래 코드 처럼 sorted() 함수의 key 매개변수에 itemgetter() 를 적용해서 해결을 할 수 가 있습니다.

Python
#  students_tuple.py
from operator import itemgetter

students = [
    ("mickle", 25, 'A'),
    ("david", 22, 'C'),
    ("jone", 31, 'C'),
]

result = sorted(students, key=itemgetter(1))
print(result)

위 코드를 실행을 해보면 아래 처럼 나이 순서대로 정렬이 되어 출력 된 것을 볼 수 있습니다.

Python
(py_study_31010) D:\Dropbox.My_Job.Study.Python
(py_study_31010) D:\Dropbox\02.My_Job\80.Study\01.Python\00.study_python_3.11.0\01.TEST>python students_tuple.py
[('david', 22, 'C'), ('mickle', 25, 'A'), ('jone', 31, 'C')]
.study_python_3.11.0.TEST>python students_tuple.py
[('david', 22, 'C'), ('mickle', 25, 'A'), ('jone', 31, 'C')]

위 코드에서 itemgetter(1) 은 students 의 아이템인 튜플의 2 번째 요소를 기준으로 정렬을 하겠다는 의미입니다.
만약에 itemgetter(2) 로 사용을 한다면 성적 순 으로 정렬을 하게 됩니다.
1 번째 요소는 이름이고, 2 번째 요소는 나이, 3 번째 요소는 성적을 의미하는 알파벳인 것입니다.

딕셔너리 정렬

그럼 이번에는 위의 students 요소가 리스트 가 아닌 딕셔너리 형태로 있다고 해보겠습니다.

Python
#  students_dict.py
from operator import itemgetter

students = [
    {"name": "mickle", "age": 25, "grade": 'A'},
    {"name": "david", "age": 22, "grade": 'C'},
    {"name": "jone", "age": 31, "grade": 'C'}
]

result = sorted(students, key=itemgetter('age'))
print(result)

위 코드처럼 딕셔너리 형태로 students 의 요소들이 있고 age 를 기준으로 정렬을 시켜 봤습니다.
결과는 아래와 같습니다.

Python
(py_study_31010) D:\Dropbox.My_Job.Study.Python
(py_study_31010) D:\Dropbox\02.My_Job\80.Study\01.Python\00.study_python_3.11.0\01.TEST>python students_dict.py
[{'name': 'david', 'age': 22, 'grade': 'C'}, {'name': 'mickle', 'age': 25, 'grade': 'A'}, {'name': 'jone', 'age': 31, 'grade': 'C'}]
.study_python_3.11.0.TEST>python students_dict.py
[{'name': 'david', 'age': 22, 'grade': 'C'}, {'name': 'mickle', 'age': 25, 'grade': 'A'}, {'name': 'jone', 'age': 31, 'grade': 'C'}]

위 처럼 나이 순서 대로 잘 정렬이 된 것을 확인 할 수 있습니다.

operator.attrgetter

operator.attrgetter 은 students 리스트 의 요소가 튜플이 아니라 Student 클래스의 객체라고 할 때 사용할 수 있습니다.

Python
#  students_class.py
from operator import attrgetter

class Student:
    def __init__(self, name, age, grade):
        self.name = name
        self.age = age
        self.grade = grade

students = [
    Student('mickle', 25, 'A'),
    Student('david', 22, 'C'),
    Student('jone', 31, 'C'),
]

result = sorted(students, key=attrgetter('age'))
print(result)

위의 코드는 attrgetter(‘age’) 가 Student 클래스의 객체인 age 속성으로 정렬을 하겠다는 의미입니다.
이전에 진행했던 것 처럼 attrgetter(‘grade’) 로 사용을 한다면 성적 순으로 정렬을 한다는 의미입니다.
위 코드를 실행시키면 아래와 같이 나옵니다

Python
(py_study_31010) D:\Dropbox.My_Job.Study.Python
(py_study_31010) D:\Dropbox\02.My_Job\80.Study\01.Python\00.study_python_3.11.0\01.TEST>python students_class.py
[<__main__.Student object at 0x000001EF1913B1C0>, <__main__.Student object at 0x000001EF1913B100>, <__main__.Student object at 0x000001EF1913B280>]
>>>
.study_python_3.11.0.TEST>python students_class.py
[<__main__.Student object at 0x000001EF1913B1C0>, <__main__.Student object at 0x000001EF1913B100>, <__main__.Student object at 0x000001EF1913B280>] >>>

위 처럼 나오는 것은 리스트에 객체의 문자열 표현(representation)이 출력된 것입니다.

각각의 요소는 main.Student object at 0x0000015E409CCC70과 같은 형태로 표시되는데, 이는 해당 객체가 main.Student 클래스의 인스턴스임을 나타냅니다. 0x0000015E409CCC70과 같은 값은 객체가 메모리에서 할당된 주소를 나타냅니다.

이 결과는 클래스의 repr 메서드가 구현되지 않았거나 기본적인 형태로 구현되었기 때문에 발생하는 것입니다. repr 메서드를 클래스에 추가하면 객체의 문자열 표현을 원하는 형태로 커스터마이즈할 수 있습니다.

  • 이 포스팅은 ‘위키독스’ 의 ‘점프 투 파이썬‘ 전자책을 구매하여 독학하기 위한 자료로 작성했습니다.
74. 파이썬 표준 라이브러리 operator.itemgetter operator.attrgetter

73. 파이썬 functools.reduce 표준 라이브러리

73. 파이썬 functools.reduce 표준 라이브러리

지난 시간에는 파이썬 표준 라이브러리 itertools.permutations 와 itertools.combinations 에 대해 알아보았습니다.
이번 포스팅에서는 파이썬 표준 라이브러리 중 functools.reduce 에 대해 공부해 보도록 하겠습니다.

파이썬 표준 라이브러리

functools.reduce

functools.reduce 함수는 functools.reduce(function, iterable) 의 형태로 사용하며 function 을 반복 가능한 객체인 iterable 의 요소에 차례 차례 좌에서 우로 누적해서 적용하며 이 객체를 하나의 값으로 줄여주는 함수 입니다.

아래 코드는 입력 인수인 num 의 요소를 모두 더해서 리턴해 주는 add 함수 입니다.

Python
#  add_num.py
def add(num):
    result = 0
    for i in num:
        result += i
    return result

num = [1, 2, 3, 4, 5]
result = add(num)
print(result)

위의 코드를 실행해 보면 아래와 같은 결과가 나옵니다.

Python
(py_study_31010) D:\Dropbox.My_Job.Study.Python
(py_study_31010) D:\Dropbox\02.My_Job\80.Study\01.Python\00.study_python_3.11.0\01.TEST>python add_num.py
15
.study_python_3.11.0.TEST>python add_num.py
15

누적 계산하기

위 코드를 functools.reduce() 함수를 이용해서 동일하게 동작하는 코드를 만들어 보겠습니다.
functools.reduce() 함수를 사용한 코드는 아래의 코드입니다.

Python
#  add_num_functools.py
import functools

num = [1, 2, 3, 4, 5]
result = functools.reduce(lambda x, y: x + y, num)
print(result)

위 코드를 실행해 보면 이전에 작성했던 코드와 마찬가지로 동일하게 15 가 출력 되는 것을 보실 수 있습니다.
이렇게 functools.reduce() 를 사용하게 되면 reduce() 에 선언했던 lambda 함수를 num 요소에 하나씩 차례대로 누적해서 적용해서 ((((1 + 2) + 3) + 4) + 5) 의 형태로 계산을 하게 됩니다.

Python
(py_study_31010) D:\Dropbox.My_Job.Study.Python
(py_study_31010) D:\Dropbox\02.My_Job\80.Study\01.Python\00.study_python_3.11.0\01.TEST>python add_num_functools.py
15
.study_python_3.11.0.TEST>python add_num_functools.py
15

결국 앞에서 만들었던 add_num.py 와 동일한 역할을 하게 됩니다.

최대값 구하기

이번에는 functools.reduce() 함수를 이용해 최대값을 구해보도록 하겠습니다.

Python
#  max_num_functools.py
import functools

num = [3, 2, 1, 8, 6, 7]
max_num = functools.reduce(lambda x, y: x if x > y else y, num)
print(max_num)

위 코드에서 처럼 [3, 2, 1, 8, 6, 7] 의 리스트 요소를 차례대로 reduce() 의 lamba 함수로 전달해서 두 값 중 큰 값을 선택하고 이렇게 반복하면서 마지막에는 남은 최대값을 리턴을 하게 됩니다.

Python
(py_study_31010) D:\Dropbox.My_Job.Study.Python
(py_study_31010) D:\Dropbox\02.My_Job\80.Study\01.Python\00.study_python_3.11.0\01.TEST>python max_num_functools.py
8
.study_python_3.11.0.TEST>python max_num_functools.py
8

최소값 구하기

Python
#  min_num_functools.py
import functools

num = [3, 2, 1, 8, 6, 7]
max_num = functools.reduce(lambda x, y: x if x < y else y, num)
print(max_num)

위 코드 처럼 부등호의 방향만 바뀌면 리스트 요소들의 최소값을 구할 수도 있습니다.

  • 이 포스팅은 ‘위키독스’ 의 ‘점프 투 파이썬‘ 전자책을 구매하여 독학하기 위한 자료로 작성했습니다.

73. 파이썬 functools.reduce 표준 라이브러리

72. 파이썬 표준 라이브러리 itertools.permutations itertools.combinations

72. 파이썬 표준 라이브러리 itertools.permutations itertools.combinations

지난 포스팅에서는 itertools.zip_longest 이라는 파이썬 표준 라이브러리에 대해 공부해 보았습니다.
이번 포스팅에서는 itertools.permutation 표준 라이브러리에 대해 공부해 보도록 하겠습니다.

파이썬 표준 라이브러리

itertools.permutations

itertools.permutations 함수는 itertools.permutations(iterable, r) 의 형태로 작성되어 사용되는데 반복 가능한 iterable 객체 중에서 r 개를 선택한 순열을 반복 가능한 객체(이터레이터)로 리턴을 해주는 함수 입니다.

1, 2, 3 의 숫자가 적힌 3 장의 카드가 있다고 했을 때 두 개의 카드를 꺼내서 만들 수 있는 2 자리 숫자를 모두 구하려면 어떻게 하는게 좋을까요?
[1, 2, 3] 3장의 카드 중에서 순서에 상관 없이 2 장을 뽑는 경우의 수는 모두 3 가지가 됩니다(조합)

  • 1, 2
  • 2, 3
  • 1, 3

그러나 위에 제시한 문제에서는 2 자리 숫자이므로 위의 3 가지에 순서를 더해 6 가지를 만들 수가 있습니다(순열)

  • 1, 2
  • 2, 1
  • 2, 3
  • 3, 2
  • 1, 3
  • 3, 1

이렇게 만들어지는 순열은 itertools.permutations 함수를 사용해서 간단하게 구할 수가 있습니다.

Python
>>> import itertools
>>> list(itertools.permutations(['1', '2', '3'], 2))
[('1', '2'), ('1', '3'), ('2', '1'), ('2', '3'), ('3', '1'), ('3', '2')]
>>>

위 코드처럼 6 가지의 경우를 만들 수 있고 여기에 아래 코드처럼 추가해서 2 자리 숫자를 만들어 볼 수 있습니다.

Python
>>> for a, b in itertools.permutations(['1', '2', '3'], 2):
...     print(a + b)
...
12
13
21
23
31
32
>>>

itertools.combinations

앞서 진행했던 예제에서 3 장의 카드에서 순서에 상관없이 2 장을 고르는 조합은 아래와 같이 itertools.combinations() 함수를 사용을 하면 됩니다.

Python
>>> import itertools
>>> list(itertools.combinations(['1', '2', '3'], 2))
[('1', '2'), ('1', '3'), ('2', '3')]
>>>

위 코드에서 보는 것 처럼 itertools.combinations 함수는 itertools.combinations(iterable, r) 의 형태로 작성이 되며 반복 가능한 객체 iterable 중에서 r 개를 선택한 조합을 반복 가능한 객체(이터레이터) 로 리턴을 해 주는 함수 입니다.

그럼 1 에서 45 까지의 숫자 중 서로 다른 숫자 6 개를 뽑는 로또 번호 처럼 모든 경우의 수(조합)을 구하고 그 개수를 출력하려면 어떻게 하면 될까요?
아래와 같이 itertools.combinations(range(1, 46), 6) 이라고 하게 되면 로또 번호를 뽑는 것처럼 1에서 45까지의 숫자 중 서로 다른 숫자 6개를 뽑는 경우의 수를 이터레이터로 리턴을 하게 됩니다.
직접 실행해 보게 되면 언제 끝날지 모르는 결과가 쭉 나올 것입니다.

Python
>>> import itertools
>>> lotto = itertools.combinations(range(1, 46), 6)
>>> for number in lotto:
...     print(number)
...
(1, 2, 3, 4, 5, 6)
(1, 2, 3, 4, 5, 7)
(1, 2, 3, 4, 5, 8)
(1, 2, 3, 4, 5, 9)
(1, 2, 3, 4, 5, 10)
...
...
...
...
...

만약 이렇게 순환하여 출력을 하지 않고 개수가 몇 개 인지만 확인하려면 아래와 같이 할 수도 있습니다.

Python
>>> len(list(itertools.combinations(range(1, 46), 6)))
8145060
>>>

위 결과처럼 로또 번호의 경우의 수는 8,145,060 개 입니다.

itertools.combinations_with_replacement

만약의 그냥 로또번호 와는 틀리게 중복이 허용이 된다면 경우의 수가 몇 개가 될까요?
[1, 2, 3, 4, 5, 5] 나 [1, 2, 3, 3, 4, 4] 처럼 같은 숫자가 여러번 나와도 상관이 없다는 의미인데 이럴 경우에는 itertools.combinations_with_replacement() 를 사용하면 됩니다.

Python
>>> len(list(itertools.combinations_with_replacement(range(1, 46), 6)))
15890700
>>>

중복이 허용이 될 경우 에는 경우의 수가 15,890,700 으로 많이 늘어나는 것을 확인 할 수 있습니다.

  • 이 포스팅은 ‘위키독스’ 의 ‘점프 투 파이썬‘ 전자책을 구매하여 독학하기 위한 자료로 작성했습니다.
72. 파이썬 표준 라이브러리 itertools.permutation

71. 파이썬 itertools.zip_longest 표준 라이브러리

71. 파이썬 itertools.zip_longest 표준 라이브러리

지난 포스팅에서 파이썬 표준 라이브러리 random 에 대해서 알아봤습니다.
이번 포스팅에서는 파이썬 표준 라이브러리 중 itertools.zip_longest 에 대해 공부해 보도록 하겠습니다.

파이썬 표준 라이브러리

itertools.zip_longest

itertools.zip_longest 함수는 같은 개수의 자료형을 묶는 파이썬 내장 함수인 zip() 과 똑같은 동작을 합니다.
그러나 itertools.zip_longest() 함수는 전달한 반복 가능한 객체의 길이가 다르면 긴 것을 기준으로 빠진 값은 fillvalue 에 설정한 값으로 채울 수가 있다는 점이 다릅니다.
itertools.zip_longest 함수의 사용되는 형식은 itertools.zip_longest(*iterable, fillvalue=None) 의 형태로 사용이 됩니다.

예를 들어 어린이집에 있는 어린이들 5명에게 간식을 나누어 주는 파이썬 코드를 작성해 보겠습니다.

Python
# snacks1.py
children = ['박영재', '한관민', '황영철', '이승민', '이보라']
snacks = ['젤리', '초콜렛', '사탕']

result = zip(children, snacks)
print(list(result))

위 코드를 실행하면 아래의 결과가 나옵니다.

Python
(py_study_31010) D:\Dropbox.My_Job.Study.Python
(py_study_31010) D:\Dropbox\02.My_Job\80.Study\01.Python\00.study_python_3.11.0\01.TEST>python snacks1.py
[('박영재', '젤리'), ('한관민', '초콜렛'), ('황영철', '사탕')]

(py_study_31010) D:\Dropbox\02.My_Job\80.Study\01.Python\00.study_python_3.11.0\01.TEST>
.study_python_3.11.0.TEST>python snacks1.py
[('박영재', '젤리'), ('한관민', '초콜렛'), ('황영철', '사탕')] (py_study_31010) D:\Dropbox.My_Job.Study.Python
(py_study_31010) D:\Dropbox\02.My_Job\80.Study\01.Python\00.study_python_3.11.0\01.TEST>python snacks1.py
[('박영재', '젤리'), ('한관민', '초콜렛'), ('황영철', '사탕')]

(py_study_31010) D:\Dropbox\02.My_Job\80.Study\01.Python\00.study_python_3.11.0\01.TEST>
.study_python_3.11.0.TEST>

위 결과를 보면 간식의 개수가 어린이집의 어린이들보다 수가 적습니다. 이처럼 children 과 snacks 의 개수가 다르므로 더 적은 snacks 의 개수 만큼만 zip() 으로 묶어 버리게 됩니다.
위 코드의 예처럼 children 이 snacks 보다 많아도 부족한 snacks 는 다른 과자인 ‘치토스’ 로 채워 간식을 나누어 주는 코드를 작성하면 어떻게 될까요?

Python
[('박영재', '젤리'), ('한관민', '초콜렛'), ('황영철', '사탕'), ('이승민', '치토스'), ('이보라', '치토스')]

위 같은 결과를 위해서 itertools.zip_longest() 함수를 사용하게 되면 개수가 많은 것을 기준으로 묶을 수가 있습니다.
여기서 부족한 항목은 None 으로 채우게 되는데, fillvalue 에 값을 지정을 해주면 None 대신 다른 값을 채울 수가 있습니다.

Python
# snacks2.py
import itertools

children = ['박영재', '한관민', '황영철', '이승민', '이보라']
snacks = ['젤리', '초콜렛', '사탕']

result = itertools.zip_longest(children, snacks, fillvalue='치토스')
print(list(result))

itertools.zip_longest 함수를 이용해 위에서 언급한 내용을 실행 시켜 보았습니다.

Python
(py_study_31010) D:\Dropbox.My_Job.Study.Python
(py_study_31010) D:\Dropbox\02.My_Job\80.Study\01.Python\00.study_python_3.11.0\01.TEST>python snacks2.py
[('박영재', '젤리'), ('한관민', '초콜렛'), ('황영철', '사탕'), ('이승민', '치토스'), ('이보라', '치토스')]
.study_python_3.11.0.TEST>python snacks2.py
[('박영재', '젤리'), ('한관민', '초콜렛'), ('황영철', '사탕'), ('이승민', '치토스'), ('이보라', '치토스')]

  • 이 포스팅은 ‘위키독스’ 의 ‘점프 투 파이썬‘ 전자책을 구매하여 독학하기 위한 자료로 작성했습니다.
71. 파이썬 표준 라이브러리 itertools.zip_longest

70. 파이썬 random 표준 라이브러리

70. 파이썬 random 표준 라이브러리

지난 포스팅에서 파이썬 표준 라이브러리 중 math.gcd 와 math.lcm 에 대해 알아 보았습니다.
이번 포스팅에서는 파이썬 표준 라이브러리 중 random 에 대해 공부 해 보도록 하겠습니다.

파이썬 표준 라이브러리

random

random.random

random 은 난수 즉 규칙이 없는 임의의 수를 발생 시키는 모듈입니다.
random 과 randint 에 대해 공부 해 보겠습니다.

먼저 0.0 에서 1.0 사이의 실수 중에서 임의의 수를 발생시키는 예를 보겠습니다.

Python
>>> import random
>>> random.random()
0.34368708037705975
>>>

위 처럼 random.random() 함수를 실행하면 기본적으로 0.0 에서 1.0 사이에서 난수를 발생하게 됩니다.

random.randint

아래 코드는 randint 를 사용해서 1 부터 10 사이의 정수 중에서 임의의 수를 발생하게 됩니다.

Python
>>> random.randint(1, 10)
6
>>>

아래 처럼 1 부터 100 사이의 정수 중 임의의 수를 발생을 시켜 보았습니다.

Python
>>> random.randint(1, 100)
31
>>>

다음 코드를 실행을 해 보겠습니다.

Python
# random_pop1.py
import random
def random_pop(data):
    number = random.randint(0, len(data) - 1)
    return data.pop(number)

if __name__ == "__main__":
    data = [1, 2, 3, 4, 5]
    while data:
        print(random_pop(data))


위 코드를 실행을 해보면 아래처럼 결과가 나옵니다.

Python
(py_study_31010) D:\Dropbox.My_Job.Study.Python
(py_study_31010) D:\Dropbox\02.My_Job\80.Study\01.Python\00.study_python_3.11.0\01.TEST>python random_pop1.py
2
4
1
5
3

(py_study_31010) D:\Dropbox\02.My_Job\80.Study\01.Python\00.study_python_3.11.0\01.TEST>
.study_python_3.11.0.TEST>python random_pop1.py
2 4 1 5 3 (py_study_31010) D:\Dropbox.My_Job.Study.Python
(py_study_31010) D:\Dropbox\02.My_Job\80.Study\01.Python\00.study_python_3.11.0\01.TEST>python random_pop1.py
2
4
1
5
3

(py_study_31010) D:\Dropbox\02.My_Job\80.Study\01.Python\00.study_python_3.11.0\01.TEST>
.study_python_3.11.0.TEST>

위에서 작성한 random_pop 함수는 리스트의 요소 중에서 무작위로 하나를 선택하여 꺼낸 후 그 꺼낸 값을 리턴을 하게 됩니다.
꺼낸 값은 pop 메서드에 의해서 없어지게 됩니다.

random.choice

random_pop 함수는 random 모듈의 choice 함수를 사용하면 좀 더 직관적으로 만들어 볼 수도 있습니다.

Python
# random_pop2.py
import random
def random_pop(data):
    number = random.choice(data)
    data.remove(number)
    return number

if __name__ == "__main__":
    data = [1, 2, 3, 4, 5]
    while data:
        print(random_pop(data))

위 코드를 실행하면 아래의 결과가 나옵니다.

Python
(py_study_31010) D:\Dropbox.My_Job.Study.Python
(py_study_31010) D:\Dropbox\02.My_Job\80.Study\01.Python\00.study_python_3.11.0\01.TEST>python random_pop2.py
1
3
5
4
2

(py_study_31010) D:\Dropbox\02.My_Job\80.Study\01.Python\00.study_python_3.11.0\01.TEST>
.study_python_3.11.0.TEST>python random_pop2.py
1 3 5 4 2 (py_study_31010) D:\Dropbox.My_Job.Study.Python
(py_study_31010) D:\Dropbox\02.My_Job\80.Study\01.Python\00.study_python_3.11.0\01.TEST>python random_pop2.py
1
3
5
4
2

(py_study_31010) D:\Dropbox\02.My_Job\80.Study\01.Python\00.study_python_3.11.0\01.TEST>
.study_python_3.11.0.TEST>

random.choice 함수는 입력으로 받은 리스트에서 무작위로 하나를 선택해서 리턴 하게 됩니다.

random.sample

리스트 요소를 랜덤하게 섞고 싶다면 random.sample 함수를 사용을 하면 됩니다.

Python
>>> a = [1, 2, 3, 4, 5]
>>> random.sample(a, len(a))
[5, 2, 4, 3, 1]
>>>

random.sample 함수에서 2 번째 인수인 len(a) 는 무작위로 추출할 원소의 갯수를 의미합니다.
만일에 random.sample(a, 3) 처럼 사용을 한다면 a 리스트에서 무작위로 3개를 추출해서 리턴을 하게 됩니다.

Python
>>> random.sample(a, 3)
[2, 1, 3]
>>>
  • 이 포스팅은 ‘위키독스’ 의 ‘점프 투 파이썬‘ 전자책을 구매하여 독학하기 위한 자료로 작성했습니다.
70. 파이썬 표준 라이브러리 random

69. 파이썬 표준 라이브러리 math.gcd math.lcm

69. 파이썬 표준 라이브러리 math.gcd math.lcm

지난 포스팅에서는 파이썬 표준 라이브러리 중 time 에 대해서 살펴보았습니다.
이번 포스팅에서는 파이썬 표준 라이브러리 중 math.gcd 와 math.lcm 에 대해 공부해 보도록 하겠습니다.

파이썬 표준 라이브러리

math.gcd

math.gcd 함수는 최대 공약수(gcd, greatest common divisor)를 쉽게 구해주는 함수 입니다.
math.gcd 함수는 파이썬 3.5 버전이상부터 사용할 수가 있습니다.

최대 공약수 에 대해 예전에는 알았지만 까먹은 분들을 위해 간단히 설명드리면
먼저 공약수(common divisor)는 두 수 이상의 여러 수의 공통 된 약수를 의미하게 됩니다.
예를 들면 30 과 15 는 공통으로 1, 3, 5, 15 라는 약수를 가지고 있습니다.
이것을 공약수라고 합니다.
이 공약수 중에서 가장 큰 공약수를 최대 공약수라고 합니다.
30 과 15 의 최대 공약수는 15가 됩니다.

다음 문제를 한 번 보겠습니다.
어린이집에서 사탕 60 개, 초콜렛 100 개, 젤리 80 개를 준비를 했습니다.
공평하게 모든 어린이들이 나누어 가지도록 봉지에 담아 나누어야 한다면 최대 몇 봉지까지 만들 수가 있을까요?
단, 사탕, 초콜렛, 젤리는 남기지 않고 모두 담도록 합니다.

이 문제는 60, 100, 80 의 최대 공약수를 구하면 바로 해결이 됩니다.
즉, 똑같이 나눌 수 있는 봉지 개수가 최대가 되는 수를 구하면 됩니다.

Python
>>> import math
>>> math.gcd(60, 100, 80)
20
>>>

파이썬의 버전이 3.9 이상이라면 math.gcd 의 인수로 위 처럼 여러개가 가능합니다.
하지만 3.9 버전 미만이라면 2 개 까지만 가능합니다.

위처럼 최대 공약수를 math.gcd 함수를 이용해서 구해보았습니다.
결론적으로 최대 20 봉지를 만들 수 있게 되고
각 봉지에 들어가는 사탕 과 초콜렛, 젤리의 갯수는 전체 개수를 20 으로 나누어서 구할 수가 있습니다.

Python
>>> 60 / 20, 100 / 20, 80 / 20
(3.0, 5.0, 4.0)
>>>

이렇게 한 봉지당 사탕 3 개, 초콜렛 5 개, 젤리 4 개씩 담으면 해결이 됩니다.

math.lcm

math.lcm 함수는 math.gcd 와는 반대 개념으로 최소 공배수를(lcm, least common multiple) 구할 때 사용되는 함수 입니다.
math.lcm 함수는 파이썬 3.9 버전부터 사용이 가능합니다.

최소 공배수에 대해서도 간략히 말씀 드리면 최대 공약수와는 반대로 두 개의 수의 공통된 배수 중 가장 작은 수를 의미 합니다.
예를 들면 3 과 5 의 최소 공배수는 15 가 됩니다.

예를 들어 버스 정류장에서 시내 버스는 15분 마다 도착을 하고 마을 버스는 25분 마다 도착을 한다고 했을 때, 오후 1시가 됐을 때 두 버스가 동시에 도착 한다고 하면 다음에 두 버스가 동시에 도착 할 시각을 알기 위해서는 어떻게 해야 할까요?

위 문제는 15 와 25 의 공통 배수 중 가장 작은 수, 즉 최소 공배수를 구하면 해결이 됩니다.

Python
>>> import math
>>> math.lcm(15, 25)
75
>>>

위 코드처럼 math.lcm 함수를 이용해서 15 와 25 의 최소 공배수 75 를 구했습니다.
오후 1시에 두 버스가 동시에 도착했다고 했었으니 다음에 동시에 도착할 시각은 75분 후가 되는 것입니다.
1시의 75분 후는 2시 15분이 되겠네요

이렇게 표준 라이브러리 math 의 최대 공약수와 최소 공배수를 구하는 math.gcd 와 math.lcm 함수에 대해 알아보았습니다.
math 라이브러리나 이전에 공부했던 time 라이브러리에는 상당히 많은 함수들이 존재합니다.
이번에 공부한 math.gcd 와 math.lcm 은 그 중 극히 일부분만 본 것임을 알고 계시기 바랍니다.

  • 이 포스팅은 ‘위키독스’ 의 ‘점프 투 파이썬‘ 전자책을 구매하여 독학하기 위한 자료로 작성했습니다.
69. 파이썬 표준 라이브러리 math.gcd math.lcm

68. 파이썬 time 표준 라이브러리

68. 파이썬 time 표준 라이브러리

지난 포스팅에서는 파이썬 표준 라이브러리 중 datetime.date 에 대해 공부 해봤습니다.
이번 포스팅에서는 파이썬 표준 라이브러리 중 time 에 대해 공부 해 보도록 하겠습니다.

파이썬 표준 라이브러리

time

time 모듈은 시간과 관련된 모듈이고 함수가 굉장히 많습니다.
그 중 몇 가지를 알아 보겠습니다

time.time

time.time() 은 UTC(Universal Time Coordinated 협정 세계 표준시) 를 사용해서 현재 시간을 실수 형태로 리턴 해주는 함수 입니다.
1970 년 1 월 1 일 0 시 0 분 0 초를 기준으로 지난 시간을 초 단위로 돌려주게 됩니다.

Python
>>> import time
>>> time.time()
1683268596.0582168
>>> 1683268596.0582168 / 60 / 60 / 24 # 며칠이 경과한지 계산
19482.275417340472
>>> 19482.275417340472 / 365 # 몇 년이 지났는지 계산
53.376097033809515
>>>

time.localtime

time.localtime 은 time.time() 이 리턴한 실수 값을 사용해서 연도와 월, 일, 시, 분, 초, … 의 형태로 바꾸어 주는 함수 입니다.

Python
>>> time.localtime(time.time())
time.struct_time(tm_year=2023, tm_mon=5, tm_mday=5, tm_hour=15, tm_min=39, tm_sec=7, tm_wday=4, tm_yday=125, tm_isdst=0)
>>>

time.asctime

time.asctime 은 위 time.localtime 에서 반환된 튜플 형태의 값을 인수로 받아서 날짜와 시간을 알아보기 쉬운 형태로 리턴을 해주는 함수입니다.

Python
>>> time.asctime(time.localtime(time.time()))
'Fri May  5 15:40:59 2023'
>>>

time.ctime

앞전에 사용한 time.asctime(time.localtime(time.time())) 를 time.ctime() 을 사용해서 간편하게 표시 할 수 있습니다. 앞전에 사용한 time.asctime 과 다른 점은 ctime 은 항상 현재 시간 만을 리턴 한다는 점입니다.

Python
>>> time.ctime()
'Fri May  5 15:43:13 2023'
>>>

time.strftime

strftime 함수는 시간에 관련된 것들을 세밀하게 표현하는 여러가지의 포맷 코드를 제공해 줍니다.

Python
time.strftime('출력할 형식 포맷 코드', time.localtime(time.time()))
시간에 관련된 것들을 표현하는 포맷 코드들
  • %a : 요일의 줄임말 (Mon)
  • %A : 요일 (Monday)
  • %b : 달의 줄임말 (Jan)
  • %B : 달 (January)
  • %c : 날짜와 시간을 출력 (06/01/01 17:22:21)
  • %d : 날 – day [01,31]
  • %H : 시간 – Hour – 24 시간 형식 [00,23]
  • %l : 시간 – Hour – 12 시간 형식 [01,12]
  • %j : 1년 중 누적 날짜 [001, 366]
  • %m : 달 [01,12]
  • % M : 분 [01,59]
  • %p : AM or PM (AM)
  • %s : 초 [00,59]
  • %U : 1년 중 누적 주 – 일요일을 시작으로 [00,53]
  • %w : 숫자로 된 요일 [0(일요일),6]
  • %W : 1년 중 누적 주 – 월요일을 시작으로 [00,53]
  • %x : 현재 설정된 로케일에 기반한 날짜 출력 (06/01/01)
  • %X : 현재 설정된 로케일에 기반한 시간 출력 (17:22:21)
  • %Y : 년도 출력 (2002)
  • %Z : 시간대 출력 (대한민국 표준시)
  • %% : 문자 (%)
  • %y : 세기부분을 제외한 년도 출력 (01)

time.strftime 을 사용하는 코드 예제입니다.

Python
>>> import time
>>> time.strftime('%x', time.localtime(time.time()))
'05/05/23'
>>> time.strftime('%c', time.localtime(time.time()))
'Fri May  5 18:52:59 2023'
>>>

time.sleep

time.sleep 함수의 경우 주로 루프 안에서 사용이 됩니다.
time.sleep 함수를 사용하게 되면 일정한 시간 간격을 두고 루프를 실행해 볼 수 있습니다.

Python
# sleep.py
import time
for i in range(10):
    print(i)
    time.sleep(1)

위의 코드를 실행을 해보면 1초 간격으로 0 부터 9 까지의 숫자를 출력을 하게 됩니다.
time.sleep 의 인수는 실수 형태를 사용 할 수 있습니다.
만약 1이면 1초, 0.5 라면 0.5 초가 되는 것입니다.~

  • 이 포스팅은 ‘위키독스’ 의 ‘점프 투 파이썬‘ 전자책을 구매하여 독학하기 위한 자료로 작성했습니다.
68. 파이썬 표준 라이브러리 time

67. 파이썬 표준 라이브러리 datetime.date

67. 파이썬 표준 라이브러리 datetime.date

지난 포스팅에서 파이썬 내장 함수에 대해 전체적으로 살펴보았습니다.
이번 포스팅 부터는 파이썬의 표준 라이브러리에 대해 공부해 보도록 하겠습니다.
먼저 datetime.date 입니다.

파이썬 표준 라이브러리

파이썬 표준 라이브러리라는 것은 전 세계의 파이썬 사용자들 중 고수 분들이 만들어 놓은 유용한 프로그램들을 모아 놓은 것을 말합니다.
표준 라이브러리를 통해 파이썬 프로그래밍에 날개를 달아 능력을 높여 줄 수 있습니다.
라이브러리는 도서관 이라는 뜻을 가지고 있는 만큼 원하는 정보를 찾아보는 곳입니다.
모든 라이브러리를 다 알 수는 없을 것입니다.
어떤 작업을 할 때 어떤 라이브러리를 사용해야 하는지 정도만 알고 있으면 됩니다.
그러기 위해서는 어떤 라이브러리가 존재하고 어떻게 사용되는지 알아야 겠죠
이번 포스팅 부터는 자주 사용되며 꼭 알아두면 좋은 라이브러리를 중심으로 공부를 해 보도록 하겠습니다.

파이썬 표준 라이브러리는 별도로 설치 과정이 필요 없습니다. 파이썬을 설치할 때 자동으로 설치가 됩니다.
sys, re 모듈은 파이썬의 중요한 라이브러리로 sys 의 경우 지난 포스팅에서 설명이 되었기에 따로 설명하지 않고 re 모듈은 이후에 진행할 포스팅에서 전체적으로 설명을 하기에 넘어가도록 하겠습니다.

datetime.date

datetime.date 라이브러리는 년, 월, 일 로 날짜를 표현할 때 사용되는 함수 입니다.
P 라는 남자가 여자친구를 2019 년 6 월 14 일 부터 만나기 시작했다면 2023 년 5 월 5 일은 만난지 며칠째 되는 날일까요?
또 만나기 시작한 2019 년 6 월 14 일 은 무슨 요일 이었을까요?
이런 문제들을 datetime.date 함수를 사용해서 쉽게 해결 할 수 있습니다.

다음처럼 년, 월, 일로 datetime.date 객체를 만들어 보겠습니다.

Python
>>> import datetime
>>> day1 = datetime.date(2019, 6, 14)
>>> day2 = datetime.date(2023, 5, 5)
>>>

days

위 코드처럼 년, 월, 일을 인수로 해서 2019 년 6월 14 일에 해당하는 날짜 객체는 day1 에
2023 년 5 월 5 일 이라는 날짜는 day 에 각각 객체를 생성을 했습니다.
이렇게 만들어진 두 날짜의 차이는 아래와 같이 뺄셈을 통해 쉽게 구할 수 있습니다.

Python
>>> diff = day2 - day1
>>> diff.days
1421
>>>

weekday

day2 에서 day1 을 뺀 diff 객체를 생성을 하고 diff 객체를 리턴을 하게 되면 두 날짜의 차이를 쉽게 확인 할 수 있습니다.
요일의 경우는 datetime.date 객체의 weekday() 함수를 사용하여 쉽게 구할 수 있습니다.

Python
>>> import datetime
>>> day = datetime.date(2019, 6, 14)
>>> day.weekday()
4
>>>

위 코드의 결과는 4 가 출력이 되었습니다.
0 은 월요일을 의미하고 이후 순서대로 1 은 화요일, 2 는 수요일, 3 은 목요일, 4 는 금요일, 5 는 토요일, 6 은 일요일이 됩니다.

isoweekday

만일 월요일이 1 부터 시작해서 화요일이 2,… 일요일이 7 을 리턴을 하게 하고 싶다면 isoweekday() 함수를 사용을 하면 됩니다.

Python
>>> day.isoweekday()
5
>>>

2019 년 6 월 14 일은 금요일 이므로 isoweekday() 함수를 사용하면 금요일을 의미하는 5 가 리턴이 됩니다.
이전에 사용한 weekday() 함수의 경우는 4 가 리턴되는 것을 확인 할 수 있습니다.

67. 파이썬 표준 라이브러리 datetime.date

  • 이 포스팅은 ‘위키독스’ 의 ‘점프 투 파이썬‘ 전자책을 구매하여 독학하기 위한 자료로 작성했습니다.
67. 파이썬 표준 라이브러리 datetime.date

66. 파이썬 내장 함수 round sorted str sum tuple type zip

66. 파이썬 내장 함수 round sorted str sum tuple type zip

지난 포스팅에서 파이썬 내장 함수 max min oct open ord pow range 까지 공부 해 봤습니다.
이번 포스팅에서는 파이썬 내장 함수 round sorted str sum tuple type 에 대해 공부해 보도록 하겠습니다.

파이썬 내장 함수

round

round 내장 함수는 숫자를 입력 받아서 반올림을 해주는 함수 입니다.
round(number[, ndigits]) 의 형태로 숫자를 입력 받습니다.
[, ndigits] 는 ndigits 가 생략이 될 수도 있다는 의미 입니다.

Python
>>> round(4.6)
5
>>> round(4.2)
4
>>>

위 코드 처럼 4.6 이란 숫자는 반올림이 되어서 5 가 리턴이 되고
4.2 라는 숫자는 반올림이 되어서 4 가 리턴이 됩니다.

Python
>>> round(5.678, 2)
5.68
>>>

위 코드는 5.678 이라는 실수를 입력 받아 소수점 2자리까지만 반올림하여 표시합니다.
이처럼 ndigits 는 반올림하여 표시하고 싶은 소수점의 자릿수를 의미합니다.

sorted

sorted 함수는 입력된 데이터를 정렬을 한 후 그 결과를 리스트로 리턴을 해 주는 함수 입니다.

Python
>>> sorted([3, 1, 2])
[1, 2, 3]
>>> sorted(['a', 'c', 'b'])
['a', 'b', 'c']
>>> sorted("zero")
['e', 'o', 'r', 'z']
>>> sorted((3, 2, 1))
[1, 2, 3]
>>>

위 코드를 보시면 처음 [3, 1, 2] 리스트를 정렬하여 [1, 2, 3] 의 리스트로 리턴을 해 주고
다음 [‘a’, ‘c’, ‘b’] 리스트는 역시 정렬이 되어 [‘a’, ‘b’, ‘c’] 의 리스트로 리턴을 해줍니다.
그 다음 “zero” 라는 문자열의 경우 ‘z’, ‘e’, ‘r’, ‘o’ 를 정렬하여 [‘e’, ‘o’, ‘r’, ‘z’] 의 리스트로 리턴을 해주고
마지막 (3, 2, 1) 역시 정렬하여 리스트 [1, 2, 3] 의 리스트로 리턴을 해주게 됩니다

리스트 자료형에도 sort 함수가 있다는 것을 공부했었습니다.
하지만 리스트 자료형에 있는 sort 함수의 경우에는 객체를 정렬을 하지만 그 결과를 리턴을 하지는 않았습니다.

str

str 내장 함수는 문자열 형태로 객체를 변환해서 리턴을 해주는 함수 입니다.

Python
>>> str(3)
'3'
>>> str('hello')
'hello'
>>>

위 코드처럼 숫자 데이터 3 을 입력했지만 ‘3’ 이라는 문자열로 리턴을 해주는 것을 확인 할 수 있습니다.

sum

sum 내장 함수는 입력된 데이터의 합을 리턴 해 주는 함수 입니다.

Python
>>> sum([1, 2, 3])
6
>>> sum([4, 5, 6])
15
>>>

위 코드 처럼 sum 함수의 입력값 1, 2, 3 의 합인 6을 출력하고
아래 4, 5, 6 의 합인 15 를 출력 해 줍니다.

tuple

tuple 내장 함수는 반복 가능한 데이터(iterable) 를 튜플로 바꿔서 리턴을 해 주는 함수 입니다.
입력된 값이 튜플이라면 그대로 리턴을 하게 됩니다.

Python
>>> tuple("python")
('p', 'y', 't', 'h', 'o', 'n')
>>> tuple([1, 2, 3])
(1, 2, 3)
>>> tuple((1, 2, 3))
(1, 2, 3)
>>>

type

type 함수는 이전에 공부하면서 가끔 봤던 적이 있는 함수 일겁니다.
입력된 값의 자료형이 무엇인지 알려 주는 함수 입니다.

Python
>>> type("python")
<class 'str'>
>>> type([ ])
<class 'list'>
>>> type(open("test", "w"))
<class '_io.TextIOWrapper'>
>>>

zip

zip 내장 함수는 동일한 갯수로 이루어진 데이터들을 묶어서 리턴을 해 주는 함수 입니다.
zip(*iterable) 의 형식으로 사용되면 *iterable 은 반복 가능한 데이터 여러 개를 입력 할 수 있다는 의미입니다.

Python
>>> list(zip([1, 2, 3], [4, 5, 6]))
[(1, 4), (2, 5), (3, 6)]
>>> list(zip([1, 2, 3], [4, 5, 6], [7, 8, 9]))
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
>>> list(zip("abc", "def"))
[('a', 'd'), ('b', 'e'), ('c', 'f')]
>>>

  • 이 포스팅은 ‘위키독스’ 의 ‘점프 투 파이썬‘ 전자책을 구매하여 독학하기 위한 자료로 작성했습니다.
66. 파이썬 내장 함수 round sorted str sum tuple type

65. 파이썬 내장 함수 max min oct open ord pow range

65. 파이썬 내장 함수 max min oct open ord pow range

지난 포스팅에서 파이썬 내장 함수 len list map 에 대해서 공부해 봤습니다.
이번 포스팅에서는 파이썬의 내장 함수 max min oct open ord pow range 에 대해 공부해 보도록 하겠습니다.

파이썬 내장 함수

max

내장 함수 max 는 반복 가능한 데이터(iterable) 를 인수로 입력을 받아 그 중 최대값을 리턴을 해주는 함수 입니다.

Python
>>> max([2, 4, 6])
6
>>> max("python")
'y'
>>>

min

min 함수는 max 함수와는 반대로 최소값을 리턴을 해주는 함수입니다.
마찬가지로 반복 가능한 데이터를 인수로 입력을 받습니다.

Python
>>> min([2, 4, 6])
2
>>> min("python")
'h'
>>>

oct

oct 함수는 이전에 공부했던 hex 와 비슷합니다.
hex 는 16진수 문자열을 리턴을 한다면 oct 는 8진수 문자열로 변경해서 리턴을 하게 됩니다.

Python
>>> oct(34)
'0o42'
>>> oct(12345)
'0o30071'
>>>

open

open 내장 함수는 open(filename, [mode])의 형태로 이루어 지며 ‘파일 이름’과 ‘읽기 방법’ 을 입력 받아서 파일 객체를 리턴을 하는 함수 입니다.
읽기 방법(mode)은 생략이 가능하며, 생략을 할 경우에는 기본값인 읽기 모드(r)로 파일 객체를 만들어서 리턴을 하게 됩니다.

open 내장 함수의 mode

w : 쓰기 모드로 파일 열기
r : 읽기 모드로 파일 열기
a : 추가 모드로 파일 열기
b : 바이너리 모드로 파일 열기

이처럼 네 가지 모드 중에서 b 모드는 w, r, a 모드와 함께 사용이 됩니다.

Python
>>> f = open("binary_file", "rb")

위 코드에서 rb 는 ‘바이너리 읽기 모드’ 를 의미합니다.

ord

ord 내장 함수는 입력 받은 문자의 유니코드 숫자 값을 리턴을 해 주는 함수 입니다.
ord 함수는 이전에 공부했던 chr 함수와 반대라고 보시면 됩니다.

Python
>>> ord('a')
97
>>> ord('가')
44032
>>>

pow

pow 내장 함수는 두 개의 입력값 x, y 를 받아서 x 의 y 제곱을 한 결과값을 리턴을 해 주는 함수 입니다.

Python
>>> pow(2, 4)
16
>>> pow(3, 3)
27
>>>

range

range 내장 함수는 for 문과 함께 자주 사용되는 함수 입니다.
range([start,] stop[,step]) 형식으로 입력을 받게 되며 입력 받은 숫자에 해당하는 범위 값을 반복 가능한 객체로 만들어서 리턴을 하게 됩니다.

인수가 하나일 경우

start 에 해당하는 시작 숫자를 지정해 주지 않을 경우 range 함수는 0 부터 시작을 하게 됩니다.

Python
>>> list(range(5))
[0, 1, 2, 3, 4]
>>>

인수가 2 개일 경우

입력으로 2 개의 인수를 주어질 경우 2 개의 인수는 시작 숫자와 끝 숫자를 나타내게 됩니다.
끝 숫자는 해당 범위에 포함이 되지 않습니다.

Python
>>> list(range(5, 10))
[5, 6, 7, 8, 9]
>>>

인수가 3 개일 경우

인수가 3 개일 경우는 위의 2 개일 경우에 step 즉, 숫자 사이의 간격을 말합니다.

Python
>>> list(range(1, 10, 2))
[1, 3, 5, 7, 9]
>>> list(range(0, -10, -1))
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
>>>

위 코드를 보시면 range(1, 10, 2) 에서 1 이 시작 숫자, 10 이 끝 숫자, 2 가 step 을 의미합니다.
1 에서 10 까지 10 을 포함하지 않는 범위에서 1 다음 2 간격을 주고 3, 다시 2 간격을 주고 5 이런식으로 리스트를 만들어 리턴을 해주었습니다.

  • 이 포스팅은 ‘위키독스’ 의 ‘점프 투 파이썬‘ 전자책을 구매하여 독학하기 위한 자료로 작성했습니다.
65. 파이썬 내장 함수 max min oct open ord pow range