블로그 이미지
조이키트 블로그
아두이노, 라즈베리파이, 반도체 센서/모듈 활용

calendar

1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30

Notice

250x250
2023. 8. 28. 15:52 파이썬
728x90
반응형

다음 코드는 간단한 해시 함수를 사용하여 정수가 키인 딕셔너리를 구현하고 있다. 여기에서 기본적인 아이디어는 intDict 클래스의 인스턴스를 해시 버킷 리스트로 나타내는 것이며, 각 버킷은 키/값의 쌍들로 이루어진 리스트이다. 각 버킷을 리스트로 구현함으로 버킷에 해시되는 값들을 리스트에 저장하여 충돌을 해결할 수 있다. 인스턴스 변수 buckets는 numBuckets의 개수만큼의 빈 리스트로 초기화한다. dictkey키로 엔트리를 검색하거나 저장하려고 할 때 해시함수 %를 사용하여 dictkey를 정수로 반환하고 그 정수를 사용하여 buckets를 인덱스하여 해당하는 dictkey와 연관된 해시 버킷을 찾아낸다. 그 다음엔 그 버킷을 선형적으로 검색하여 dictkey키로 된 엔트리가 있는지 확인한다. 검색을 하는 경우에는 그 키로 된 엔트리가 없다면 None을 반환한다. 저장을 하려고 하는 경우에는 이미 들어가 있는 엔트리가 있다면 그 엔트리의 값을 대체하거나 엔트리가 없다면 새로운 엔트리를 추가한다.

# 해싱을 사용하여 딕셔너리 구현하기
class intDict(object):
    def __init__(self, numBuckets):
        self.buckets = []
        self.numBuckets = numBuckets
        for i in range(numBuckets):
            self.buckets.append([])

    def addEntry(self, dictKey, dictVal):
        hashBucket = self.buckets[dictKey%self.numBuckets]
        for i in range(len(hashBucket)):
            if hashBucket[i][0] == dictKey:
                hashBucket[i] = (dictKey, dictVal)
                return
        hashBucket.append((dictKey, dictVal))

    def getValue(self, dicKey):
        hashBucket = self.buckets[dicKey%self.numBuckets]
        for e in hashBucket:
            if e[0] == dicKey:
                return e[1]
            return None
        
    def __str__(self):
        result = '{'
        for b in self.buckets:
            for e in b:
                result = result + str(e[0]) + ':' + str(e[1]) + ', '
                return result[:-1] + '}'
            
import random
D = intDict(29)
for i in range(20):
    key = random.randint(0, 10**5)
    D.addEntry(key, i)

print('The value of the intDict is:')
print(D)
print('\n', 'The buckets are:')
for hashBucket in D.buckets:
    print(' ', hashBucket)

__str__ 메소드에서 보면 요소들이 추가된 순서에 관계없이 키가 해시하려는 값의 순서로 딕셔너리를 만들고 있다는 것을  알 수가 있다. 이것이 dict 자료형의 키의 순서를 왜 예측할 수 없는지를 설명해준다. 위의 코드는 먼저 20개의 엔트리로 intDict를 만든다. 엔트리의 값은 정수 0에서 19이다. 키는 0과 10^5 -1 사이의 정수 중 하나를 임의로 선택한다. 그 다음에는 클래스에 정의된 __str__ 메소드를 사용하여 intDict를 출력한다. 마직막으로 D.bucket을 반복하여서 각 해시 버킷을 출력한다.

 

출력 결과

The value of the intDict is:
{957:7,}

 The buckets are:
  [(957, 7)]
  [(96745, 4), (19373, 5), (1567, 19)]
  [(86799, 12)]
  []
  []
  [(79726, 1)]
  []
  [(43101, 10), (36112, 18)]
  [(74886, 16)]
  []
  []
  [(62042, 13)]
  []
  [(68018, 6)]
  []
  []
  []
  [(83508, 17)]
  [(192, 2)]
  []
  []
  [(10722, 3), (99839, 14)]
  []
  [(34620, 0)]
  [(18381, 9), (33490, 11)]
  []
  []
  [(22792, 15)]
  [(79952, 8)]

만약 추상화 장벽을 무시하고 intDict을 직접 살펴보면 많은 해시 버킷이 비어있는 것을 확인할 수 있다. 비어있지 않은 버킷은 충돌 횟수에 따라 하나에서 세 개의 튜플을 갖고 있다.

728x90
반응형
posted by 조이키트 블로그
2023. 8. 28. 14:35 파이썬
728x90
반응형

합병 정렬은 전형적인 분할정복 알고리즘으로 볼 수 있으며 1945년에 존 폰 노이만이 개발하였고 아직까지도 많이 사용되고 있다. 분할 정복 알고리즘처럼 재귀적으로 가장 쉽게 설명할 수 있다.

1. 리스트의 길이가 0이나 1일 때 리스트는 이미 정렬된 상태이다.

2. 리스트에 한 개 이상의 요소가 들어있으면 리스트를  두 개의 리스트로 나눈 후에 합병정렬을  사용하여 나뉘어진 리스트를 정렬한다.

3. 결과를 합병한다.

우선 각 리스트의 첫 번째 요소를 보고 둘 중 작은 요소를 결과 리스트의 끝으로 옮기는 것이다. 만약 둘 중 하나의 리스트가 비게 되면, 남아있는 리스트의 요소들을 모두 결과 리스트에 옮기면 된다.

 

다음 코드는 두 개의 배치 함수를 정의하고 있으며 이 두 함수를 이용하여 두 가지 방법으로 리스트를 정렬하고 있다. 각 함수는 표준 파이썬 모듈 string을 가져와서 그 모듈의 split 함수를 사용한다. split의 인자는 두개의 문자열들이고 두번 째 인자는 문자열을 부분열로 나눌 때 사용하는 구분자를 나타낸다. 

# 이름 리스트 정렬하기
def merge(left, right, compare):
    result = []
    i, j = 0, 0
    while i < len(left) and j < len(right):
        if compare(left[i], right[j]):
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1

    while (i < len(left)):
        result.append(left[i])
        i += 1
    while (j < len(right)):
        result.append(right[j])
        j += 1
    return result

import operator

def mergeSort(L, compare = operator.lt):
    if len(L) < 2:
        return L[:]
    else:
        middle = len(L)//2
        left = mergeSort(L[:middle], compare)
        right = mergeSort(L[middle:], compare)
        return merge(left, right, compare)
    
from string import *
def lastNameFirstName(name1, name2):
    name1 = name1.split(' ')
    name2 = name2.split(' ')
    if name1[1] != name2[1]:
        return name1[1] < name2[1]
    else : 
        return name1[0] < name2[0]
    
def firstNameLastName(name1, name2):
    name1 = name1.split(' ')
    name2 = name2.split(' ')
    if name1[0] != name2[0]:
        return name1[0] < name2[0]
    else:
        return name1[1] < name2[1]
    
L = ['Chris Terman', 'Tom Brady', 'Eric Grimson', 'Gisels Bundchen']
newL = mergeSort(L, lastNameFirstName)
print('Sorted by last name =', newL)
newL = mergeSort(L, firstNameLastName)
print('Sorted by first name =', newL)

L = [3, 5, 2]
D = {'a' : 12, 'c' : 5, 'b' : 'dog'}
print(sorted(L))
L.sort()
print(L)
print(sorted(D))

파이썬 함수 sorted은 리스트나 딕셔너리처럼 반복 가능한 객체를 첫 번째 인자로 받아서 정렬된 새로운 리스트를 반환한다.

 

출력 결과

Sorted by last name = ['Tom Brady', 'Gisels Bundchen', 'Eric Grimson', 'Chris Terman']
Sorted by first name = ['Chris Terman', 'Eric Grimson', 'Gisels Bundchen', 'Tom Brady']
[2, 3, 5]
[2, 3, 5]
['a', 'b', 'c']

sorted 함수를 딕셔너리에 실행하면 딕셔너리의 키 값으로 정렬한 리스트를 반환한다. list.sort 메소드와 sorted 함수 모두 두 개의 추가 매개변수를 사용할 수가 있다. key 매개변수는 합병정렬에서 compare와 같은 역할을 하는 것으로 비교 함수를 제공하기 위한 것이다. reverse 매개변수는 리스트가 오름차순인지 내림차순인지를 지정해준다. 다음 코드는 L의 요소들을 내림차순으로 정렬하여 출력한다.

L = [[1,2,3], (3,2,1,0), 'abc']
print(sorted(L, key = len, reverse=True))

출력 결과

[(3, 2, 1, 0), [1, 2, 3], 'abc']

list.sort 메소드와 sorted 함수는 안전 정렬 함수이다. 즉 비교할 때 두 개의 요소가 같다면 원래 리스트의 순서가 상대적으로 적용되어 최종 리스트에도 원래 순서로 유지가 된다.

728x90
반응형
posted by 조이키트 블로그
2023. 8. 16. 10:30 파이썬
728x90
반응형

알고리즘의 실행 시간과 입력 규모의 관계를 말할 때에는 점근 표기법이라는 것을 공식적으로 사용한다.

점근 표기법은 입력 규모가 무한대로 갈 때의 알고리즘의 복잡도를 의미한다.

# 점근 표기법
def f(x):
    ans = 0
    for i in range(1000): # Loop that takes constant time
        ans += 1
    print('Number of additions so far', ans)

    for i in range(x): # Loop that takes time x
        ans += 1
    print('Number of additions so far', ans)

    for i in range(x): # Nested loops take time x**2
        for j in range(x):
            ans += 1
            ans += 1
    print('Number of additions so far', ans)
    return ans


print(f(2))

위의 코드를 보면 각 줄의 코드를 실행할 때 한 단위의 시간이 걸린다고 가정한다면 이 함수의 실행 시간은 1000 + x + 2x^2로 표현할 수 있다. 상수 1000은 첫 번째 반복문이 실행되는 횟수에 해당한다. x는 두 번째 반복문이 실행되는 횟수에 해당한다. 마지막으로 2x^2는 중첩된 반복문에 있는 두 개의 문장을 실행한 것에 해당한다.

만약 f(2)을 호출한다면 다음과 같이 출력된다.

Number of additions so far 1000
Number of additions so far 1002
Number of additions so far 1010
1010

 

728x90
반응형
posted by 조이키트 블로그
2023. 8. 12. 17:35 파이썬
728x90
반응형

프로그램은 Mertagate 클래스와 다음과 같은 세 가지 종류에 해당하는 하위 클래스로 구성한다.

1. 포인트가 없는 고정 금리 대출

2. 포인트가 있는 고정 금리 대출

3. 초기 티져금리로 시작하고 대출 기간 동안 금리가 올라가는 대출

# 대출(Mortgage) 기본 클래스
def findPayment(loan, r, m):
    return loan*((r*(1+r)**m)/((1+r)**m - 1))

class Mortgage(object):
    def __init__(self, loan, annRate, months):
        self.loan = loan
        self.rate = annRate/12.0
        self.months = months
        self.paid = [0.0]
        self.owed = [loan]
        self.payment = findPayment(loan, self.rate, months)
        self.legend = None

    def makePayment(self):
        self.paid.append(self.payment)
        reduction = self.payment - self.owed[-1]*self.rate
        self.owed.append(self.owed[-1] - reduction)

    def getTotalPaid(self):
        return sum(self.paid)
    
    def __str__(self):
        return self.legend

 위의 코드를 보면 추상 클래스 Mertgate가 있다. 이 클래스는 각 하위 클래스에서 함께 사용하는 메소드를 가지고 있지만 직접 인스턴스를 생성하기 위한 클래스는 아니다.

def findPayment(loan, r, m):
    return loan*((r*(1+r)**m)/((1+r)**m - 1))

첫 번째 함수 findPayment는 주어진 기간에 대출을 모두 갚기 위해 은행에 상환해야 할 원금과 이자를 포함한 고정된 월 납입금을 계산해준다.

class Mortgage(object):
    def __init__(self, loan, annRate, months):
        self.loan = loan
        self.rate = annRate/12.0
        self.months = months
        self.paid = [0.0]
        self.owed = [loan]
        self.payment = findPayment(loan, self.rate, months)
        self.legend = None

__init__을 살펴보면 모든 Mertgage의 인스턴스들이 가지고 있는 인스턴스 변수들은 다음과 같다. 초기 대출 금액, 한달 금리, 대출 기간 개월 수, 매월 초에 상환된 금액 리스트(첫 번째 달에는 아무 금액도 상환하지 않기 때문에 리스트는 0.0으로 시작한다.) 매월 초에 미결제된 잔액의 리스트, 매월 내는 납입금(findPayment 함수가 반환하는 값으로 초기화 된다.) 모든 Mertgate의 하위 클래스들은 __init__은 제일 먼저 Mertgage.__init__을 호출하고 그 다음에 self.legend를 각각 하위 클래스에 쓰여져 있는 설명대로 알맞게 초기화해야 한다.

    def makePayment(self):
        self.paid.append(self.payment)
        reduction = self.payment - self.owed[-1]*self.rate
        self.owed.append(self.owed[-1] - reduction)

makePayment 메소드는 대출 납입금을 기록하기 위한 용도이다. 각 납입금은 대출 잔액으로 인한 이자를 포함한 것이며, 그 나머지는 대출 잔금을 줄여 나간다. 이것 때문에 makePayment는 self.paid와 self.owed이 두 값 모두를 갱신한다.

    def getTotalPaid(self):
        return sum(self.paid)

getTotalPaid 메소드는 일련의 숫자들의 합을 반환해주는 파이썬 내장 함수 sum을 사용한다. 만약 숫자가 아닌 값이 있다면 예의를 발생한다.

다음 코드는 두 종류의 대출의 클래스를 구현하고 있다. 각 클래스는 __init__ 함수를 올버라이드하고 있으며 Mortgage에서 또 다른 세 가지 메소드를 상속받고 있다.

# 고정 금리 대출 클래스
class Fixed(Mortgage):
    def __init__(self, loan, r, months):
        Mortgage.__init__(self, loan, r, months)
        self.legend = 'Fixed, ' + str(r*100) + '%'

class FixedWithPts(Mortgage):
    def __init__(self, loan, r, months, pts):
        Mortgage.__init__(self, loan, r, months)
        self.pts = pts
        self.paid = [loan*(pts/100.0)]
        self.legend = 'Fixed, ' + str(r*100) + '%, '\
        + str(pts) + ' points'

 다음은 Mortgage의 세번쨰 하위 클래스이다. TwoRate 클래스는 마치 두 개의 다른 금리를 가지고 있는 대출을 병합한 것처럼 다루고 있다. self.paid가 0.0으로 초기화되어 있기 때문에 지불한 횟수보다 하나 더 많은 값을 가지고 있다. 때문에 makePayment는 len(self.paid)를 self.teaserMonths + 1과 비교하고 있는 것이다.

# 티져금리와 대출
class TwoRate(Mortgage):
    def __init__(self, loan, r, months, teaserRate, teaserMonths):
        Mortgage.__init__(self, loan, teaserRate, months)
        self.teaserMonths = teaserMonths
        self.teaserRate = teaserRate
        self.nextRate = r/12.0
        self.legend = str(teaserRate*100)\
        + '% for' + str(self.teaserMonths)\
        + 'months, then' + str(r*100) + '%'

    def makePayment(self):
        if len(self.paid) == self.teaserMonths + 1:
            self.rate = self.nextRate
            self.payment = findPayment(self.owed[-1], self.rate, self.months - self.teaserMonths)
        Mortgage.makePayment(self)

다음은 세 종류의 대출 모두의 비용을 샘플 매개변수로 계산 후 출력해주는 함수는 함수이다. 각 종류마다 클래스들을 생성한 후, 주어진 햇수로 매달 상환해야 할 금액을 계산한다. 끝으로 각 대출마다 총 상환액을 출력한다. 

# 대출 금액 계산하기
def compareMortgages(amt, years, fixedRate, pts, ptsRate, varRate1, varRate2, varMonths):
    totMonths = years*12
    fixed1 = Fixed(amt, fixedRate, totMonths)
    fixed2 = FixedWithPts(amt, ptsRate, totMonths, pts)
    twoRate = TwoRate(amt, varRate2, totMonths, varRate1, varMonths)
    morts = [fixed1, fixed2, twoRate]
    for m in range(totMonths):
        for mort in morts:
            mort.makePayment()
        for m in morts:
            print(m)
            print('Total payment = $' + str(int(m.getTotalPaid())))

출력 결과

Fixed, 7.000000000000001%
Total payment = $479017
Fixed, 5.0%, 3.25 points
Total payment = $393011
4.5% for 48 months, then 9.5%
Total payment = $551444
728x90
반응형

'파이썬' 카테고리의 다른 글

파이썬 (합병 정렬과 이름 리스트 정렬하기)  (0) 2023.08.28
(파이썬) 점근 표기법  (0) 2023.08.16
(파이썬) Grades 클래스  (0) 2023.08.12
(파이썬) 상속/Inheritance  (0) 2023.08.09
(파이썬) Person 클래스  (0) 2023.08.09
posted by 조이키트 블로그
2023. 8. 12. 12:58 파이썬
728x90
반응형

아래 코드는 여러 학생들의 성적을 관리할 수 있는 클래스이다. 리스트와 딕셔너리를 사용하여 Grades 클래스의 인스턴스들을 구현하였다. 리스트는 수업의 학생들을 관리하고 딕셔너리는 각 학생들의 일련번호를 성적에 연결하고 있다.

getGrades는 한 학생의 성적 리스트를 복사해서 반환하고, getStudents는 학생 리스트를 복사해서 반환하고 있다. 

# Grades 클래스
def Grades(object):
    def __init__(self):
        self.students = []
        self.grades = {}
        self.isSorted = True

def addStudent(self, student):
    if student in self.students:
        raise ValueError('Duplicate student')
    self.students.append(student)
    self.grades[student.getIdNum()] = []
    self.isSorted = False

def addGrade(self, student, grade):
    try:
        self.grade[student.getIdNum()].append(grade)
    except:
        raise ValueError('Student not in mapping')
    
def getGrades(self, student):
    try:
        return self.grades[student.getIdNum()][:]
    except:
        raise ValueError('Student not in mapping')
    
def getStudents(self):
    if not self.isSorted:
        self.students.sort()
        self.isSorted = True
    return self.students[:]

isSorted의 인스턴스 변수는 학생 리스트에서 새로운 학생들이 추가되고 난 이후에 정렬되었는지 아닌지를 알기 위해서 사용된다. 이것을 통해 getStudents가 이미 정렬된 리스트를 또 다시 정렬하지 않도록 도와준다.

728x90
반응형

'파이썬' 카테고리의 다른 글

(파이썬) 점근 표기법  (0) 2023.08.16
(파이썬) 대출 금액 계산 프로그램  (0) 2023.08.12
(파이썬) 상속/Inheritance  (0) 2023.08.09
(파이썬) Person 클래스  (0) 2023.08.09
(파이썬) 추상 데이터 타입과 클래스  (0) 2023.08.07
posted by 조이키트 블로그
2023. 8. 9. 14:30 파이썬
728x90
반응형

상속은 연관된 추상화를 가진 그룹들을 편리하게 만들 수 있도록 도와준다. 상속을 통하여 각 타입들이 상대적으로 더 상위 계층인 타입의 속성을 상속받게 하는 타입 계층을 생성하는 것을 가능하게 도와준다. object  클래스는 이 계층의 최상층에 있다. person이 object의 모든 속성들을 상속받기 때문에 프로그램은 person에 변수를 바인딩할 수 있고 또한 person을 리스트에 추가하는 것 등을 할 수 있다.

# Person 클래스
import datetime

class Person(object):
    def __init__(self, name):
        self.name = name
        try:
            lastBlank = name.rindex(' ')
            self.lastName = name[lastBlank+1:]
        except:
            self.lastName = name
        self.birthday = None

    def getName(self):
        return self.name
    
    def getLastName(self):
        return self.lastName
    
    def setBirthday(self, birthdate):
        self.birthday = birthdate

    def getAge(self):
        if self.birthday == None:
            raise ValueError
        return (datetime.date.today() - self.birthday).days
    
    def __It__(self, other):
        if self.lastName == other.lastName:
            return self.name < other.name
        return self.lastName < other.lastName
    
    def __str__(self):
        return self.name

# MITPerson 클래스
class MITPerson(Person):
    nextIdNm = 0 #idendification number
    def __init__(self, name):
        Person. __init__(self, name)
        self.idNum = MITPerson.nextIdNm
        MITPerson.nextIdNm += 1

    def getIdNum(self):
        return self.idNum
    
    def __It__(self, other):
        return self.idNum < other.idNum

위의 MITPerson 클래스는 부모 클래스인 Person의 속성들을 상속받고 있다. 상속받는 속성 중에는 Person이 object에게 상속받는 모든 속성들도 포함하고 있다. 객체지향 프로그래밍에서 MITPerson는 Person의 하위 클래스이다. 그러므로 부모 클래스의 속성들을 상속받는다. 뿐만 아니라 하위 클래스는 다음을 할 수 있다.

- 새로운 속성을 추가할 수 있다. MITPerson은 클래스 변수 nextIdNum, 인스턴스 변수 idNum, 메소드 getIdNum을 추가하였다.

- 부모 클래스의 속성을 오버라이드 할 수 있다. MITPerson은 __init__ 함수와 __It__ 함수를 오버라이드 하였다.

메소드 MITPerson. __init__은 먼저 Person. __intit__을 호출하여 상속받은 인스턴스 변수인 self.name을 초기화한다. 그 후에 Person 객체들에는 없지만 MITPerson에 새롭게 추가한 인스턴스 변수 self.idNum을 초기화한다.

인스턴스 변수 self.idNum은 인스턴스의 변수가 아닌 MITPerson의 클래스 변수 nextIdNum를 사용하여 초기화한다.

MITPerson의 인스턴스가 생성되면 nextIdNum는 클래스 변수이기 때문에 새로 생성되지 않는다. 때문에 __init__에서 MITPerson이 더 확실하게 중복되지 않는 idNum을 가질 수 있도록 할 수 있다.

p1 = MITPerson('Barbara Beaver')
print(str(p1) + '\'s id number is ' + str(p1.getIdNum()))

첫 번째 줄은 새로운 MITPerson의 인스턴스를 생성한다. str(p1)을 실행하려고 하면 런타임 시스템은 먼저 MITPerson 클래스에 __str__메소드가 정의되어 있는지 확인한자. 위의 경우 __str__ 메소드가 없기 때문에 MITPerson의 부모 클래스 Person에 __str__ 메소드가 있는지 확인한다. 만약 런타임 시스템이 p1.getidNum()을 실행하려고 할 때 우선 MITPerson에 이 메소드가 있는지 확인한다. 

 

출력결과 

Barbara Beaver's id number is 0

 

728x90
반응형

'파이썬' 카테고리의 다른 글

(파이썬) 대출 금액 계산 프로그램  (0) 2023.08.12
(파이썬) Grades 클래스  (0) 2023.08.12
(파이썬) Person 클래스  (0) 2023.08.09
(파이썬) 추상 데이터 타입과 클래스  (0) 2023.08.07
(파이썬) 예외 처리하기  (0) 2023.08.06
posted by 조이키트 블로그
2023. 8. 9. 11:31 파이썬
728x90
반응형

여기서는 날짜에 관해서 편리한 기능을 제공하는 표준 파이썬 라이브러리 모듈 datetime을 사용하고 있다.

# Person 클래스
import datetime

class Person(object):
    def __init__(self, name):
        self.name = name
        try:
            lastBlank = name.rindex(' ')
            self.lastName = name[lastBlank+1:]
        except:
            self.lastName = name
        self.birthday = None

    def getName(self):
        return self.name
    
    def getLastName(self):
        return self.lastName
    
    def setBirthday(self, birthdate):
        self.birthday = birthdate

    def getAge(self):
        if self.birthday == None:
            raise ValueError
        return (datetime.date.today() - self.birthday).days
    
    def __It__(self, other):
        if self.lastName == other.lastName:
            return self.name < other.name
        return self.lastName < other.lastName
    
    def __str__(self):
        return self.name

다음 코드는 Person 클래스를 사용하고 있다.

me = Person('Joy Kit')
him = Person('Jae Sung')
her = Person('Jyung Un Hyang')
print('His last name is ', him.getLastName())
print('My name is ', me.getName())
me.setBirthday(datetime.date(2023, 5, 25))
him.setBirthday(datetime.date(1958, 8, 27))
her.setBirthday(datetime.date(1991, 2, 19))
print(me.getName(), 'is', me.getAge(), 'days old')
print(him.getName(), 'is', him.getAge(), 'days old')
print(her.getName(), 'is', her.getAge(), 'days old')

출력 결과

His last name is  Sung
My name is  Joy Kit
Joy Kit is 74 days old
Jae Sung is 23721 days old
Jyung Un Hyang is 11857 days old

앞의 코드에서 Person의 인스턴스가 생길 때마다 __init__ 함수에 인자가 전달됨을 볼 수 있다.

예를 들어 pList가 Person을 요소로 가진 리스트라고 하면 pList.sort()를 호출하면 Person 클래스에 정의되어있는 __it__ 메소드를 사용해서 정렬하게 될 것이다.

pList = [me, him, her]
for p in pList:
    print(p)
pList.sort()
for p in pList:
    print(p)

출력결과

Joy Kit
Jae Sung
Jyung Un Hyang
728x90
반응형

'파이썬' 카테고리의 다른 글

(파이썬) Grades 클래스  (0) 2023.08.12
(파이썬) 상속/Inheritance  (0) 2023.08.09
(파이썬) 추상 데이터 타입과 클래스  (0) 2023.08.07
(파이썬) 예외 처리하기  (0) 2023.08.06
(파이썬) 문자 번역하기  (0) 2023.08.05
posted by 조이키트 블로그
2023. 8. 7. 13:10 파이썬
728x90
반응형

추상 데이터 타입은 일련의 객체들과 그 객체들에게 적용할 작업을 뜻한다. 이 두가지가 묶여 있는 이유는 프로그램의 한 지점에서 다른 지점으로 객체를 넘길 때 그 객체의 데이터 속성을 접근할 뿐만 아니라 그 데이터를 쉽게 조작할 수 있는 작업까지도 넘길 수 있기 때문이다.

파이썬에서는 클래스를 사용하여 데이터 추상화를 구현한다. 클래스 정의는 type이라는 타입을 가진 객체를 생성하고 그 객체를 instancemethod이라는 타입을 가진 일련의 객체들과 연결시켜 준다. 예를 들어 IntSet.insert는 IntSet이라는 클래스에 정의된 insert라는 메소드를 뜻하는 것이다.

# IntSet 클래스
class IntSet(object):
    def __init__(self):
        self.vals = []

    def insert(self, e):
        if not e in self.vals:
            self.vals.append(e)

    def member(self, e):
        return e in self.vals
    
    def remove(self, e):
        try:
            self.vals.remove(e)
        except:
            raise ValueError(str(e) + 'not found')
        
    def getMembers(self):
        return self.vals[:]
    
    def __str__(self):
        self.vals.sort()
        result = ''
        for e in self.vals:
            result = result + str(e) + ','
        return '{' + result[:-1] + '}' #-1 omits trailing comma
    
print(type(IntSet), type(IntSet.insert))

위의 코드를 실행하면 다음과 같은 결과가 나온다.

출력 결과

<class 'type'> <class 'function'>

클래스는 다음 두 가지 작업을 지원한다.

인스턴스 생성은 새로운 클래스의 인스턴스를 만들 때 사용된다. 예를 들어 s = IntSet()은 IntSet 타입의 새로운 객체를 생성한다. 이 객체를 IntSet의 인스턴스라고 부른다.

속성 레퍼런스는 점 표기법을 사용하여 클래스의 속성에 접근한다. 예를 들어 s.member는 IntSet 타입의 인스턴스인 s에 연관된 메소드 member를 의미한다. 

여기 기술된 InSet 클래스 정의의 첫 줄은 IntSet이 object의 하위 클래스라는 것을 명시하고 있다. 파이썬은 두 개의 밑줄 표시로 시작하고 끝나는 특별한 메소드들이 몇 개 있다. 클래스의 인스턴스를 생성할 때마다 클래스에 정의된 __init__ 메소드를 호출하게 된다. 그러면 인터프리터는 IntSet 타입의 새로운 인스턴스를 생성하고 IntSet.__init__ 메소드를 호출한다. 클래스의 인스턴스와 연결된 메소드는 점 표기법을 사용해 호출한다.

s = IntSet()
s.insert(3)
print(s.member(3))

위의 코드는 IntSet의 새로운 인스턴스를 생성한 후 int형 3을 IntSet에 삽입한다. 출력 결과는 True이다.

클래스에서 가장 마지막으로 정의된 메소드 __str__은 또 다른 특별한 메소드이다. print문을 사용하면 print를 하려는 객체와 연관된 __str__ 함수가 자동으로 호출된다.

s = IntSet()
s.insert(3)
s.insert(5)
print('OUTPUT : ', s)

출력 결과

OUTPUT :  {3,5}
728x90
반응형

'파이썬' 카테고리의 다른 글

(파이썬) 상속/Inheritance  (0) 2023.08.09
(파이썬) Person 클래스  (0) 2023.08.09
(파이썬) 예외 처리하기  (0) 2023.08.06
(파이썬) 문자 번역하기  (0) 2023.08.05
(파이썬) 딕셔너리(Dictionary)  (1) 2023.08.04
posted by 조이키트 블로그
2023. 8. 6. 09:06 파이썬
728x90
반응형

 

# 예외 처리하기
while True:
    val = input('Enter an integer: ')
    try:
        val = int(val)
        print('The square of the number you entered is', val**2)
        break # to exit the while loop
    except ValueError:
        print(val, 'is not an integer')

while문에 들어가면 프로그램은 사용자에게 정수를 입력하도록 요청할 것이다. 사용자가 무언가를 입력하였다면 프로그램은 try-except 블록을 실행한다. 만약 try문에 있는 두 구문들이 ValueError 예외를 발생시키지 않는다면 break문이 실행되고 while문을 빠져나온다. 하지만 만약 try 블록에서 ValueError 예외가 발생하면 코드를 건너뛰어서 except 블록으로 간다.

Enter an integer: 3.3
3.3 is not an integer
Enter an integer: 3
The square of the number you entered is 9

만약 사용자가 정수로 나타낼 수 없는 문자열을 입력한다면 프로그램은 사용자에게 또 다른 값을 입력하도록 요청할 것이다. 사용자가 어떤 문자를 입력하든지 절대로 처리되지 않는 예외는 발생하지 않을 것이다.

Enter an integer: ㅁ
ㅁ is not an integer
Enter an integer: s
s is not an integer
Enter an integer: d
d is not an integer
Enter an integer: f
f is not an integer
Enter an integer: 3
The square of the number you entered is 9

위의 코드는 사용자에게 정수를 입력하도록 요청하는 곳이 많다면 문제가 될 수 있다. 이것을 함수로 하면 쉽게 해결할 수 있다.

# 함수를 사용한 예의 처리하기
def readInt():
    while True:
        val = input('Enter an integer: ')
        try:
            val = int(val)
            return print(val, 'is an integer')
        except ValueError:
            print(val, 'is not an integer')

print(readInt())

출력 결과

Enter an integer: 2.5
2.5 is not an integer
Enter an integer: 8
8 is an integer
None

이것보다 더 좋은 것은 이 함수를 일반화하여 어느 종류의 입력 값을 입력 받을 수 있도록 하는 것이다.

def readVal(valType, requestMsg, errorMsg):
    while True:
        val = input(requestMsg + ' ')
        try:
            val = valType(val)
            return val
        except ValueError:
            print(val, errorMsg)

val = readVal(int, 'Enter an integer : ', 'is not an integer')

print(val, 'is an integer')

출력 결과 

Enter an integer :  3.3
3.3 is not an integer
Enter an integer :  3
3 is an integer

readVal 함수는 다형성, 즉 다양한 자료형의 매개변수를 사용할 수가 있다. 파이썬에서 자료형은 일급 객체이기 때문에 함수들을 작성하기가 쉽다.

728x90
반응형
posted by 조이키트 블로그
2023. 8. 5. 10:22 파이썬
728x90
반응형

 

# 문자 번역하기
EtoF = {'bread':'pain', 'wine':'vin', 'with':'avec', 'I':'Je',
        'eat':'mange', 'drink':'bois', 'John':'Jean',
        'friends':'amis', 'and':'et', 'of':'du', 'red':'rouge'}
FtoE = {'pain':'bread', 'vin':'wine', 'avec':'with', 'Je':'I',
        'mange':'eat', 'bois':'drink', 'Jean':'John',
        'amis':'friends', 'et':'and', 'du':'of', 'rouge':'red'}

dicts = {'English to French' :EtoF, 'French to English':FtoE}

def translateWord(word, dictionary):
    if word in dictionary.keys():
        return dictionary[word]
    elif word !='':
        return '"' + word + '"'
    return word

def translate(phrase, dicts, direction):
    UCLetters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    LCLetters = 'abcdefghijklmnopqrstuvwxyz'
    letters = UCLetters + LCLetters
    directionay = dicts[direction]
    translation = ''
    word = ''
    for c in phrase:
        if c in letters:
            word = word + c
        else:
             translation = translation + translateWord(word, directionay) + c
             word = ''
    return translation + ' ' + translateWord(word, directionay)

print(translate('I drink good red wine, and eat bread.',dicts, 'English to French'))
print(translate('Je bois du vin rouge.',dicts, 'French to English'))

 

출력 결과

Je bois "good" rouge vin, et mange pain. 
I drink of wine red.

리스트와 같이 딕셔너리에는 많은 유용한 메소드들이 있다. 튜플처럼 변형 불가능한 객체들은 딕셔너리의 키로 사용할 수 있다.

 

딕셔너리에 공통적으로 사용 가능한 연산들

len(d) : d에 들어있는 개수를 반환한다.

d.keys() : d에 들어있는 키들을 리스트로 반환한다.               (python 2.x)

                 d에 들어있는 키들을 dict_keys로 반환한다.         (python 3.x)

d.values() : d에 들어있는  값들을 리스트로 반환한다.            (python 2.x)

                    d에 들어있는 키들을 dict_values로 반환한다.   (python 3.x)

k in d : d에 키 k가 있을 때 True를 반환한다.

d[k] : d에서 키 k와 쌍인 값을 반환한다.

d.get(k, v) : d에 k가 있을 때 d[k]를 반환하며 없을 경우 v를 반환한다.

d[k] = v : d에서 값 v를 키 k와 연결한다. 만약 k에 이미 연결된 값이 있을 경우 그 값을 대체한다.

del d[k] : 키 k를 d에서 제거한다.

for k in d : d에 들어있는 키를 하나씩 돌아가면서 접근한다.

728x90
반응형
posted by 조이키트 블로그
2023. 8. 4. 16:33 파이썬
728x90
반응형

dict 자료형의 객체들은 리스트와 달리 인덱스가 정수여야 할 필요가 없으며, 변형 불가능한 어떤 값이라도 가능하다는 점을 제외하면 리스트와 같다. 순서대로 정렬되어 있지 않기 때문에 인덱스가 아닌 키를 사용해야 한다. 딕셔너리는 키/값으로 된 쌍이로 생각하면 된다. dict 자료형의 상수들은 중괄호를 사용해서 표현하고 각 요소들은 키와 그 뒤에 콜론 그리고 값으로 표현한다.

 

문자열에 관한 메소드

s.count(s1) : s에서 s1이 몇 번 나타나는지 센다.

s.find(s1) : s에서 s1이 처음 나타난 곳의 인덱스를 반환하여 없을 경우 -1을 반환한다.

s.rfind(s1) : find와 같으나 s의 끝에서부터 시작한다.

s.index(s1) : find와 같으나 s에 s1이 없을 경우 예외를 발생시킨다.

s.rindex(s1) : index와 같으나 s의 끝에서부터 시작한다.

s.lower() : s에 있는 모든 대문자를 소문자로 변환한다.

s.replace(old, new) : s에서 모든 문자열 old를 new로 대체한다.

s.rstrip() : s에서 오른 편에 있는 공백을 제거한다.

s.split(d) : 구분 문자 d를 사용해서 s를 나눈다. s의 하위 문자열로 구성되어 있는 리스트를 반환한다. 

 

다음 예를 살펴보면

# 딕셔너리
monthNumbers = {'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr' : 4, 'May' : 5,
                1: 'Jan', 2: 'Feb', 3: 'Mar', 4: 'Apr', 5: 'May'}
print('The third month is ' +monthNumbers[3])
dist = monthNumbers['Apr'] - monthNumbers['Jan']
print('Apr and Jan are', dist, 'months apart')

출력 결과

The third month is Mar
Apr and Jan are 3 months apart

딕셔너리에 들어가는 값들은 순서대로 되어있지 않기 때문에 인덱스로 접근할 수 없다. 때문에 monthNumbers[1]은 딕셔너리에 두 번째로 들어간 값이 아니라 키가 1인 것을 의미한다.

keys 메소드는 딕셔너리의 키를 담고 있는 리스트를 반환한다. 키의 순서는 정의되어 있지 않으므로 print(monthNumbers.key())를 실행해 보면 키의 순서가 다음과 같이 나올 수도 있다.

dict_keys(['Jan', 'Feb', 'Mar', 'Apr', 'May', 1, 2, 3, 4, 5])

딕셔너리에서 for문을 사용해서 값들을 접근할 경우 반복 변수는 키/값의 쌍이 아니라 키이다.

keys = []
for e in monthNumbers:
    keys.append(e)
keys.sort()
print(keys)

출력 결과

TypeError: '<' not supported between instances of 'int' and 'str'

 

python 3.x의 경우 서로 다른 자료형들을 비교 연산하는 것이 가능하지 않으므로 에러 메시지를 출력한다. 딕셔너리는 파이썬의 큰 장점 중 하나이다. 다양한 프로그램을 작성할 때 생길 수 있는 어려움들을 크게 해소해준다.

728x90
반응형
posted by 조이키트 블로그
2023. 8. 4. 14:22 파이썬
728x90
반응형

시퀀스 자료형의 공통점과 차이점

seq[i] : 시퀀스에서 i번째 요소를 반환한다.

len(seq) : 시퀀스의 길이를 반환한다.

seq1 + seq2 : 두 시퀀스를 합친것을 반환한다.

n * seq : seq를 n번동안 반복한 시퀀스를 반환한다.

seq[start:end] : 시퀀스의 슬라이스를 반환한다.

e in seq : 시퀀스에 e가 있으면 True를 반환하고 없으면 False를 반환한다.

for e in seq : 시퀀스의 요소들을 하나씩 돌아가면서 접근한다.

 

자료형 구성 요소의 자료형 예시 가변성
str 문자 ' ', 'a', 'abc' 없음
tuple 모든 자료형 ( ), (3, ), ('abc', 4) 없음
list 모든 자료형 [ ], [3], ['abc'],  있음

 

리스트는 변형 가능하기 때문에 계산하면서 점차적으로 리스트를 구성할 수 있다.

다음의 코드는 어떤 리스트에 있는 짝수 값들을 가진 리스트를 점차적으로 만든다.

evenElems = []
for e in L:
    if e%2 == 0:
        evenElems.append(e)

튜플은 불변성이기 때문에 엘리어싱 또한 걱정할 필요가 없다는 장점이 있다. 또한 리스트와 다르게 딕셔너리에서 키로 사용할 수 있다. 

문자열은 문자만 담을 수 있기 때문에 튜플이나 리스트처럼 다양하게 사용하는 것이 제한되어 있다. 반면에 문자열을 사용하다 보면 많은 내장 메소드 때문에 편하게 프로그래밍을 할 수 있다.

728x90
반응형
posted by 조이키트 블로그
2023. 8. 4. 13:57 파이썬
728x90
반응형

파이썬에서 함수는 일급 객체이다. 즉 함수는 int나 list와 같은 모든 자료형들과 같이 객체로 취급할 수 있다는 뜻이다. 함수에도 자료형이 있기 때문에 예를 들어 type (fact)라는 수식을 입력하면 <type 'function'>이라는 결과가 나온다.

# 함수를 리스트의 요소로 사용하기
def applyToEach(L, f):
    for i in range(len(L)):
        L[i] = f(L[i])

def factR(n):
    if n == 1:
        return n
    else:
        return n*factR(n-1)
    
def fib(n):
    if n == 0 or n ==1:
        return 1
    else:
        return fib(n-1) + fib(n-2)

L = [1, -2, 3.33]
print('L =', L)
print('Apply abs to each element of L.')
applyToEach(L, abs) # 절대 값
print('L =', L)
print('Apply int ot each element of', L)
applyToEach(L, int) 
print('L =', L)
print('Apply factorial to each element of', L)
applyToEach(L, factR)
print('L =', L)
print('Apply Fibonnaci to each element of', L)
applyToEach(L, fib)
print('L =', L)

함수 applyToEach는 함수로 된 인자를 가지고 있기 때문에 고차함수라 불린다 . 처음 호출되었을 때 applyToEach는 단항 내장 함수인 abs를 각 요소에 적용하여  리스트 L을 변형시킨다. 두 번째 호출되었을 때는 각 요소를 형식 변환한다. 세번째 호출되었을 때는 각 요소들에 정의된 factR 함수를 적용한다. 네 번째 호출되었을 때는 각 요소들에게 정의된 fib 함수를 적용한다. 

 

출력 결과

L = [1, -2, 3.33]
Apply abs to each element of L.
L = [1, 2, 3.33]
Apply int ot each element of [1, 2, 3.33]
L = [1, 2, 3]
Apply factorial to each element of [1, 2, 3]
L = [1, 2, 6]
Apply Fibonnaci to each element of [1, 2, 6]
L = [1, 2, 13]
728x90
반응형
posted by 조이키트 블로그
2023. 8. 4. 13:57 파이썬
728x90
반응형

파이썬에서 함수는 일급 객체이다. 즉 함수는 int나 list와 같은 모든 자료형들과 같이 객체로 취급할 수 있다는 뜻이다. 함수에도 자료형이 있기 때문에 예를 들어 type (fact)라는 수식을 입력하면 <type 'function'>이라는 결과가 나온다.

# 함수를 리스트의 요소로 사용하기
def applyToEach(L, f):
    for i in range(len(L)):
        L[i] = f(L[i])

def factR(n):
    if n == 1:
        return n
    else:
        return n*factR(n-1)
    
def fib(n):
    if n == 0 or n ==1:
        return 1
    else:
        return fib(n-1) + fib(n-2)

L = [1, -2, 3.33]
print('L =', L)
print('Apply abs to each element of L.')
applyToEach(L, abs) # 절대 값
print('L =', L)
print('Apply int ot each element of', L)
applyToEach(L, int) 
print('L =', L)
print('Apply factorial to each element of', L)
applyToEach(L, factR)
print('L =', L)
print('Apply Fibonnaci to each element of', L)
applyToEach(L, fib)
print('L =', L)

함수 applyToEach는 함수로 된 인자를 가지고 있기 때문에 고차함수라 불린다 . 처음 호출되었을 때 applyToEach는 단항 내장 함수인 abs를 각 요소에 적용하여  리스트 L을 변형시킨다. 두 번째 호출되었을 때는 각 요소를 형식 변환한다. 세번째 호출되었을 때는 각 요소들에 정의된 factR 함수를 적용한다. 네 번째 호출되었을 때는 각 요소들에게 정의된 fib 함수를 적용한다. 

 

출력 결과

L = [1, -2, 3.33]
Apply abs to each element of L.
L = [1, 2, 3.33]
Apply int ot each element of [1, 2, 3.33]
L = [1, 2, 3]
Apply factorial to each element of [1, 2, 3]
L = [1, 2, 6]
Apply Fibonnaci to each element of [1, 2, 6]
L = [1, 2, 13]
728x90
반응형
posted by 조이키트 블로그
2023. 8. 4. 13:53 파이썬
728x90
반응형

파이썬에서 함수는 일급 객체이다. 즉 함수는 int나 list와 같은 모든 자료형들과 같이 객체로 취급할 수 있다는 뜻이다. 함수에도 자료형이 있기 때문에 예를 들어 type (fact)라는 수식을 입력하면 <type 'function'>이라는 결과가 나온다.

# 함수를 리스트의 요소로 사용하기
def applyToEach(L, f):
    for i in range(len(L)):
        L[i] = f(L[i])

def factR(n):
    if n == 1:
        return n
    else:
        return n*factR(n-1)
    
def fib(n):
    if n == 0 or n ==1:
        return 1
    else:
        return fib(n-1) + fib(n-2)

L = [1, -2, 3.33]
print('L =', L)
print('Apply abs to each element of L.')
applyToEach(L, abs) # 절대 값
print('L =', L)
print('Apply int ot each element of', L)
applyToEach(L, int) 
print('L =', L)
print('Apply factorial to each element of', L)
applyToEach(L, factR)
print('L =', L)
print('Apply Fibonnaci to each element of', L)
applyToEach(L, fib)
print('L =', L)

함수 applyToEach는 함수로 된 인자를 가지고 있기 때문에 고차함수라 불린다 . 처음 호출되었을 때 applyToEach는 단항 내장 함수인 abs를 각 요소에 적용하여  리스트 L을 변형시킨다. 두 번째 호출되었을 때는 각 요소를 형식 변환한다. 세번째 호출되었을 때는 각 요소들에 정의된 factR 함수를 적용한다. 네 번째 호출되었을 때는 각 요소들에게 정의된 fib 함수를 적용한다. 

 

출력 결과

L = [1, -2, 3.33]
Apply abs to each element of L.
L = [1, 2, 3.33]
Apply int ot each element of [1, 2, 3.33]
L = [1, 2, 3]
Apply factorial to each element of [1, 2, 3]
L = [1, 2, 6]
Apply Fibonnaci to each element of [1, 2, 6]
L = [1, 2, 13]
728x90
반응형
posted by 조이키트 블로그
2023. 8. 4. 13:03 파이썬
728x90
반응형

리스트 조건 제시법은 시퀀스로 된 값들을 다룰 수 있는 간편한 방법을 제공한다. 새로운 리스트가 생성되고 어떤 시퀀스(예를 들어 또 다른 리스트에 있는 요소들)에 있는 값에 대해 주어진 작업을 수행하고, 그 결과값으로 새로운 리스트를 생성한다.

# 리스트 조건 제시법
L = [x**2 for x in range(1,7)]
print(L)

출력 결과

[1, 4, 9, 16, 25, 36]

리스트 조건 제시법의 for문 뒤에는 하나 이상의 if나 for문로 생성된 값에 적용할 for문이 따라올 수 있다. 이렇게 추가되는 구문들은 첫 번째 for문에서 생성한 일련의 값들을 수정하고 조건 제시법과 연관된 작업을 적용시킨 새로운 일련의 값들을 생성한다.

mixed = [1, 2, 'a', 3, 4.0]
print([x**2 for x in mixed if type(x) == int])

이 코드는 mixed에 있는 리스트를 제곱한 후에[1, 4, 9]를 출력한다.

[1, 4, 9]

 

728x90
반응형
posted by 조이키트 블로그
2023. 8. 4. 12:36 파이썬
728x90
반응형

리스트 조건 제시법은 시퀀스로 된 값들을 다룰 수 있는 간편한 방법을 제공한다. 새로운 리스트가 생성되고 어떤 시퀀스(예를 들어 또 다른 리스트에 있는 요소들)에 있는 값에 대해 주어진 작업을 수행하고, 그 결과값으로 새로운 리스트를 생성한다.

# 리스트 조건 제시법
L = [x**2 for x in range(1,7)]
print(L)

출력 결과

[1, 4, 9, 16, 25, 36]

리스트 조건 제시법의 for문 뒤에는 하나 이상의 if나 for문로 생성된 값에 적용할 for문이 따라올 수 있다. 이렇게 추가되는 구문들은 첫 번째 for문에서 생성한 일련의 값들을 수정하고 조건 제시법과 연관된 작업을 적용시킨 새로운 일련의 값들을 생성한다.

mixed = [1, 2, 'a', 3, 4.0]
print([x**2 for x in mixed if type(x) == int])

이 코드는 mixed에 있는 리스트를 제곱한 후에[1, 4, 9]를 출력한다.

[1, 4, 9]

 

728x90
반응형
posted by 조이키트 블로그
2023. 8. 4. 12:25 파이썬
728x90
반응형

파이썬은 for문에서 반복문이 한 번 돌고 날 때마다 증가되는 내부 카운터를 사용하여 리스트에서 실행되는 지점을 따라가도록 설계되었다. 만약 카운터의 값이 증가하다가 리스트 길이와 같은 값에 도달하면 반복문이 종료된다.

# 복제하기(Cloning)
def removeDups(L1, L2):
    for e1 in L1:
        if e1 in L1:
            L1.remove(e1)

L1 = [1,2,3,4]
L2 = [1,2,4,6]
removeDups(L1, L2)
print('L1 =', L1)

위 예제의 경우 숨겨진 카운터가 0에서 시작하여 L1[0]이 L2에 있다는 것을 발견하고는 리스트에서 제거한다. 그래서 L1의 길이가 3이 된다. 그리고서 카운터는 1 증가하고 L1[1]이 L2에 있는지 확인하게 된다. 하지만 이것은 L1[1]이 원래 가지고 있었던 값(즉 2)가 아니라 2가 제거된 후의 L1[1]의 값, 즉 3이다. 그러므로 보시다시피 리스트가 반복문 안에서 수정된다면 원하는 결과를 얻지 못하게 되는것이다.

 

출력결과

L1 = [2, 4]
728x90
반응형
posted by 조이키트 블로그
2023. 8. 4. 12:06 파이썬
728x90
반응형

파이썬은 for문에서 반복문이 한 번 돌고 날 때마다 증가되는 내부 카운터를 사용하여 리스트에서 실행되는 지점을 따라가도록 설계되었다. 만약 카운터의 값이 증가하다가 리스트 길이와 같은 값에 도달하면 반복문이 종료된다.

# 복제하기(Cloning)
def removeDups(L1, L2):
    for e1 in L1:
        if e1 in L1:
            L1.remove(e1)

L1 = [1,2,3,4]
L2 = [1,2,4,6]
removeDups(L1, L2)
print('L1 =', L1)

위 예제의 경우 숨겨진 카운터가 0에서 시작하여 L1[0]이 L2에 있다는 것을 발견하고는 리스트에서 제거한다. 그래서 L1의 길이가 3이 된다. 그리고서 카운터는 1 증가하고 L1[1]이 L2에 있는지 확인하게 된다. 하지만 이것은 L1[1]이 원래 가지고 있었던 값(즉 2)가 아니라 2가 제거된 후의 L1[1]의 값, 즉 3이다. 그러므로 보시다시피 리스트가 반복문 안에서 수정된다면 원하는 결과를 얻지 못하게 되는것이다.

 

출력결과

L1 = [2, 4]
728x90
반응형
posted by 조이키트 블로그
2023. 8. 4. 10:16 파이썬
728x90
반응형

튜플과 마찬가지로 for문을 사용하여 리스트의 모든 요소를 돌아가며 접근할 수 있다.

# for문을 사용한 리스트와 가변성
Techs = ['MIT', 'Caltech']
Ivys = ['Harvard', 'Yale', 'Brown']

Univs = [Techs, Ivys]
Univs1 = [['MIT', 'Caltech'], ['Harvard', 'Yale', 'Brown']]
Techs.append('RPI')

for e in Univs:
    print('Univs contains', e)
    print('which contains')
    for u in e:
        print(' ', u)

출력 결과

Univs contains ['MIT', 'Caltech', 'RPI']
which contains
  MIT
  Caltech
  RPI
Univs contains ['Harvard', 'Yale', 'Brown']
which contains
  Harvard
  Yale
  Brown

Techs.append(RPI) 명령어처럼 리스트에 또 다른 리스트를 끝에 추가할 떄 추가하는 리스트의 구조는 유지된다. 즉 리스트 형태로 리스트 끝에 삽입되는 것이다. 만약 원래의 리스트 구조를 유지하지 않고 리스트에 있는 요소를 다른 리스트에 삽입하려고 한다면 리스트 합치기나 extend 메소드를 사용하면 된다.

# extend와 append를 사용한 리스트의 접근성
L1 = [1,2,3]
L2 = [4,5,6]
L3 = L1 + L2
print('L3 =', L3)
L1.extend(L2)
print('L1 =', L1)
L1.append(L2)
print('L1 =', L1)

출력 결과

L3 = [1, 2, 3, 4, 5, 6]
L1 = [1, 2, 3, 4, 5, 6]
L1 = [1, 2, 3, 4, 5, 6, [4, 5, 6]]

리스트에 삽입할 때 연산자 +를 사용하거나 extend를 사용한 경우 삽입하려는 값이 리스트 형태로 삽입되지 않고 요소들만 삽입된 것을 볼 수 있다. 출력된 결과를 보면 연산자 +는 새로운 리스트를 생성하고 반환한다. 그와 반대로 extend와 append는 L1을 변형시킨다.

 

※ 리스트에 관한 몇 개의 주요 메소드들

L.append(e) : L의 끝에 객체 e를 추가한다.

L.count(e) : L안에 있는 e의 개수를 반환한다.

L.insert(i, e) : L의 i번째 인덱스에 객체 e를 삽입한다.

L.extend(L1) : L1의 요소들을 L의 끝에 추가한다.

L.remove(e) : L에서 나타나는 첫 번째 e를 삭제한다.

L.index(e) : L에서 나타나는 첫 번째 e의 인덱스를 반환한다. 만약 e가 L에 없는 경우 예외가 발행한다.

L.pop(i) : L의 i번째 인덱스에 있는 값을 반환과 동시에 리스트에서 제거한다. i의 값이 생략된 경우 i는 디폴드 값인 -1가 되며 L의 마지막 요소를 반환하고 리스트에서 제거한다.

L.sort() : L에 있는 요소들을 오름차순으로 정렬한다.

L.reverse() : L에 있는 요소들의 순서를 반대로 배열한다.

728x90
반응형
posted by 조이키트 블로그
prev 1 2 next