본문 바로가기

배운 책들 정리/혼자 공부하는 파이썬

혼자 공부하는 파이썬 4 - 문자열, 리스트, 딕셔너리와 관련된 기본 함수(while,range,reversed,enumerate,Counter 등등)

4장 반복문

1. 리스트와 반복문

1) while 문 * 3초 동안 반복하는 프로그램

# 반복문 while
# 시간을 기반으로 반복
# 유닉스 타임 = 1970년 1월 1일 0시 0분 0초를 기준으로 몇초가 지났는지 알려줌
# 3초 동안 반복하는 프로그램

import time  # time 모듈 불러오기
no = 0  # no 변수 초기화
target = time.time() + 3  # 3초 후의 시간을 target 변수에 저장
while time.time() < target :  # 현재 시간이 target 시간보다 작을 때까지 반복
 no +=1  # no 변수에 1씩 더해줌
 print(no)  # no 값 출력

 

* 실행 종료 선택 프로그램 break, continue

# 키워드 break
i = 0  # 초기값 설정
while True:  # 무한루프
    print(i)  # i 출력
    i += 1  # i 증가
    yn = input("종료할까요?(원하시면 y나 Y를 입력하세요)> ")  # 사용자 입력 받기
    if yn in ["y", "Y"]:  # yn 값이 "y"나 "Y"와 같으면
        print("반복 종료")  # "반복 종료" 출력
        break  # 반복문 종료
# 키워드 continue
no = [100, 10, 110, 20]
for i in no:
  if i <= 100:  # i가 100 이하인 경우 아래 코드를 실행하지 않고 다음 반복으로 넘어감
    continue
  else:
    print(i)  # i가 100보다 큰 경우 i를 출력함

 

2) 247p~249문제 !!! 중요

* 1번 (range문제)

# 1-2번 문제 247p
a=list(range(7,0,-1))
print(a)

* 2번 문제 (for문을 통한 dict 생성)

# 2번 문제 248p
# 딕셔너리 생성을 위한 키, 값 리스트 생성
key_list = ["name", "hp", "mp", "level"]
value_list = ["기사", 200, 30, 5]

# 빈 딕셔너리 생성
character = {}

# key_list와 value_list를 이용하여 딕셔너리 생성
for i in range(len(key_list)):
    character[key_list[i]] = value_list[i]

# 생성된 딕셔너리 출력
print(character)

 

* 3번 문제 (while문, break를 통한 최종 값 구하기 // 10000이 넘는 경우를 구하기)

# 3번 문제 248p # break를 넣을 경우

# 이 코드는 먼저, 10000이라는 값을 limit에 할당합니다. 
# 그리고 i와 sum_value 변수를 1과 0으로 초기화합니다. 
# while 루프에서는 무한 루프를 돌면서 sum_value에 i 값을 더해주고, 
# 만약 sum_value가 limit보다 크거나 같아지면 break 문을 이용해서 while 루프를 빠져나옵니다. 
# 마지막으로 print 함수를 이용해 i, limit, sum_value를 출력합니다. 
# 이 코드는 1부터 차례대로 더해가면서 limit보다 커지는 순간을 찾아내는 방법을 이용하여 i와 sum_value를 출력합니다.

# limit 변수에 최대 더해질 수 있는 값(최댓값)을 할당합니다.
limit = 10000 

# i 변수에 첫번째 더할 값인 1을 할당하고, sum_value 변수에 초기값 0을 할당합니다.
i = 1
sum_value = 0

# while 루프를 돌면서 sum_value에 i 값을 더해주고, sum_value가 limit 이상이 되면 루프를 중단합니다.
while True:
    sum_value += i
    
    if sum_value >= limit:
        break
        
    # i 값에 1을 더해줍니다.
    i += 1
    
# 결과를 출력합니다.
print("{}를 더할 때 {}을 넘으며 그때의 값은 {}입니다.".format(i, limit, sum_value))
# 3번 문제 248p # break를 넣지 않은 경우 (print에서 조절)
limit = 10000  # 더한 결과가 이 값 이상이 되면 루프를 멈춥니다.
i = 1  # 더할 정수를 1부터 시작합니다.
sum_value = 0  # 더한 결과를 담을 변수입니다.

while sum_value <= limit:
    sum_value += i
    i += 1
    
print("{}를 더할 때 {}을 넘으며 그때의 값은 {}입니다.".format(i-1, limit, sum_value))

 

*4번 문제 249p (for문과 if문을 활용하여 최대가 되는 경우를 구하기 // 범위 range 활용)

# 4번 문제 249p
max_value = 0  # 최대값을 저장할 변수
a = 0  # 최대값일 때의 i 값
b = 0  # 최대값일 때의 j 값

for i in range(1, 51):  # i는 1부터 50까지 반복
    j = 100 - i  # i와 j의 합이 100이 되도록 j를 계산
    value = i * j  # i와 j의 곱을 계산
    if value > max_value:  # 곱이 현재까지의 최대값보다 크면 최대값과 최대값일 때의 i, j 값을 갱신
        max_value = value
        a = i
        b = j

print("최대가 되는 경우: {} * {} = {}".format(a, b, max_value))  # 최대값일 때의 i, j 값과 곱을 출력

* 위의 계산 식을 직접 보면서 배우는 팁

a = []; b = []; c = []

# 1부터 5까지 반복하면서 j값 구하고 a, b, c 리스트에 append
for i in range(1, 5+1):
    j = 10 - i
    current = i * j
    a.append(i)
    b.append(j)
    c.append(current)

# a, b, c 리스트 출력
print(a)
print(b)
print(c)

 

3) 문자열,리스트,딕셔너리와 관련된 함수 

* min,max,sum

# 함수
# 리스트에 사용할 수 있는 함수
a = [1,2,3,4,5]
print(min(a))
print(max(a))
print(sum(a))

* reversed

# 요소 순서 거꾸로 바꾸기
a = [1,2,3,4,5]
b = reversed(a)
print(a)
print(b)
print(list(b))

# 변수로 쓰지 말고 함수 적용을 바로 써야 함
a = reversed([1,2,3,4,5])
for i in a:
  print(i)

for i in a:
  print(i)
# 변수로 쓰지 말고 함수 적용을 바로 써야 함
for i in reversed([1,2,3,4,5]):
  print(i)

for i in reversed([1,2,3,4,5]):
  print(i)

* index & 값 출력

# 인덱스 & 값 출력
# 1) 리스트 반복
example_list = ["A", "B", "C"]
i = 0

# 리스트 example_list를 반복하면서 인덱스 i와 해당 값을 출력한다.
for j in example_list:
  print(i, j)

  # 인덱스 i를 1씩 증가시킨다. # 다음 인덱스로 이동하기 위해 i에 1 더하기
  i += 1
# 2) 범위 & 리스트 반복
example_list = ["A","B","C"]
for i in range(len(example_list)): # example_list 길이 만큼 반복
  print(i,example_list[i]) # i와 example_list[i] 출력

# 3) enumerate() => 튜플 형태로 반환
# enumerate()를 사용하여 리스트를 인덱스와 함께 출력하는 코드
example_list = ["A","B","C"]
print(example_list) # 리스트 전체 출력
print(enumerate(example_list)) # enumerate() 함수 사용시 객체 출력
for i,j in enumerate(example_list): # enumerate() 함수로 i는 인덱스, j는 값으로 각각 반복문에서 사용
  print(i,j)

* dict 튜플 이해하기

# 딕셔너리의 키와 값을 출력하는 코드
example_dictionary = {
    "키1": "값1",
    "키2": "값2",
    "키3": "값3"
}
for i, j in example_dictionary.items():  # items() 메소드로 키와 값을 각각 변수 i와 j에 할당하고 반복
    print(i, j)  # 각각의 i와 j를 출력
# 리스트 내포
# 1부터 5까지의 숫자 리스트를 만들고, 그 리스트를 이용해 각 원소의 제곱을 구하는 코드
a = []  # 빈 리스트 a 생성
b = []  # 빈 리스트 b 생성
for i in range(1,5+1):  # 1부터 5까지 반복
  a.append(i)  # 리스트 a에 i를 추가
  b.append(i **2)  # 리스트 b에 i의 제곱을 추가
print(a)  # 리스트 a 출력
print(b)  # 리스트 b 출력
c=[i**2 for i in range(1,5+1)]
print(c) # 리스트 내포를 사용하여 1부터 5까지 제곱한 값을 c 리스트에 저장하고 출력

# 리스트 내포에서 조건문 추가
# "토마토"를 제외한 과일만 리스트 b에 추가하는 코드
a = ["사과", "체리", "딸기", "토마토", "복숭아"]
b = [fruit for fruit in a if fruit != "토마토"]
print(b) # 리스트 b 출력

* 들여쓰기 문제

# 여러 줄의 문자열을 출력할 때 들여쓰기가 되는 문제 해결
no = int(input("정수 입력>"))
if no % 2 == 0: # 짝수
    # 여러 줄의 문자열을 출력할 때는 맨 앞에 "\"를 붙여서 해결할 수 있다.
    print("""\
입력한 숫자는 {}입니다. 
{}는 짝수입니다.""".format(no,no))
else: # 홀수
    # 여러 줄의 문자열을 출력할 때는 맨 앞에 "\"를 붙여서 해결할 수 있다.
    print("""\
입력한 숫자는 {}입니다.
{}는 홀수입니다.""".format(no,no))
# 여러 줄의 문자열을 출력할 때 코딩의 들여쓰기 통일성이 저해되는 문제를 해결하기 위해
# 문자열 앞에 \를 붙여서 들여쓰기가 되는 문제를 해결합니다.
no = int(input("정수 입력>"))
if no % 2 == 0: # 짝수
    print("""\
입력한 숫자는 {}입니다. 
{}는 짝수입니다.""".format(no, no))
else: # 홀수
    print("""\
입력한 숫자는 {}입니다.
{}는 홀수입니다.""".format(no, no))
# 여러 줄의 문자열을 출력할 때 코딩의 들여쓰기 통일성이 저해 되는 문제
no = int(input("정수 입력>"))
if no % 2 == 0: # 짝수
  print("""입력한 숫자는 {}입니다.\n{}는 짝수입니다.""".format(no,no))
else: # 홀수
  print("""입력한 숫자는 {}입니다.\n{}는 홀수입니다.""".format(no,no))

* join 사용

no = int(input("정수 입력>"))
if no % 2 == 0: # 짝수
  print("\n".join(["입력한 숫자는 {}입니다.\n{}는 짝수입니다."]).format(no,no))
else: # 홀수
  print("\n".join(["입력한 숫자는 {}입니다.\n{}는 홀수입니다."]).format(no,no))

* 이터레이터

# 이터레이터
a = [1,2,3]
b = reversed(a)
print(b)
# print(list(b))
print(next(b))
print(next(b))
print(next(b))

 

4) 확인 문제 !!! 266p

* 1번 문제 enumerate()함수와 items()함수의 올바른 표기법

enumerate() : enumerate(리스트)

items() : 딕셔너리.itmes()

 

* 2번 문제

# 266p~267p
# 1번 문제는 2,3번
# 2번 문제 (1~100 사이에 있는 숫자 중 2진수로 변환했을 때 
# 0이 하나만 포함된 숫자를 찾고, 그 숫자들의 합을 구하는 코드를 만들어 보세요.)

output = []  # 2진수에서 0이 하나만 있는 숫자들을 저장할 리스트 생성

for i in range(1,101):  # 1부터 100까지의 수에 대해 반복
  binary = bin(i)[2:]  # i를 2진수로 변환하여 문자열 형태로 저장 (첫 두 글자 "0b"는 제외)
  if binary.count("0") == 1:  # 2진수에서 "0"의 개수가 1인 경우
    output.append(i)  # output 리스트에 i 추가

for i in output:  # output 리스트에 저장된 숫자들에 대해 반복
  print("{} : {}".format(i, "{:b}".format(i)))  # 숫자와 해당 숫자의 2진수 표기 출력
print("합계:",sum(output))  # output 리스트에 저장된 숫자들의 합 출력

# 2번 문제 교수님 풀이
# 리스트 내포를 사용하여 코드를 간결하게 작성
output = [i
          for i in range(101)  # 1부터 100까지의 숫자를 대상으로 함
          if "{:b}".format(i).count("0") == 1]  # 2진수 변환 후 0의 개수가 1인 숫자를 선택
for i in output:
  print("{} : {}".format(i, "{:b}".format(i)))  # 선택된 숫자와 2진수 출력
print("합계:", sum(output))  # 선택된 숫자들의 합을 계산하여 출력
# 2번 문제 교수님 풀이 수정 부분 // if i !=0 추가
output = [i   # 1부터 100까지 반복하며
          for i in range(101)
          if "{:b}".format(i).count("0") == 1] # i를 이진수로 변환하여 0의 개수가 1인 경우에만 리스트에 추가

for i in output: # output 리스트의 요소들에 대해서 반복
  if i != 0: # i가 0일 경우 이진수 변환 시 '0'이 반환되기 때문에 제외
    print("{} : {}".format(i, "{:b}".format(i))) # i와 i를 이진수로 변환한 결과 출력
print("합계:", sum(output)) # output 리스트의 합 출력

 

 

 

5) 도전문제!!!! 268p

 

* 1번 문제 - 숫자의 종류를 구하기

** 교수님 풀이

# 1번 문제 // 교수님 풀이
a = [1, 2, 3, 4, 1, 2, 3, 1, 4, 1, 2, 3] # 주어진 리스트 a 생성
b = {} # 빈 딕셔너리 b 생성
for i in a: # 리스트 a의 모든 요소에 대해서 반복문 실행
    if i in b: # 만약 딕셔너리 b에 현재 요소 i가 이미 있다면
        b[i] += 1 # 해당 요소의 개수를 1 증가시킴
    else: # 만약 딕셔너리 b에 현재 요소 i가 없다면
        b[i] = 1 # 해당 요소의 개수를 1로 설정함

print("{}에서".format(a))
print("사용된 숫자의 종류는 {}개입니다.".format(len(b))) # b의 길이를 이용하여 사용된 숫자의 종류의 개수를 출력함
print("참고: {}".format(b)) # 딕셔너리 b를 출력하여 각 숫자가 몇 번 사용되었는지 나타냄

 

** 나

# 1번 문제 (숫자의 종류) 268p
# 주어진 리스트 a에서 각 숫자가 몇 번 사용되었는지 딕셔너리로 저장
a = [1,2,3,4,1,2,3,1,4,1,2,3]
b = {i: a.count(i) for i in set(a)}

# 결과 출력
print("{}에서\n사용된 숫자의 종류는 {}개입니다.\n참고: {}".format(a, len(set(a)), b))

 

* 2번 문제 - 염기의 개수

** 교수님

# 2번 문제 교수님 // 대문자 입력 안 됨, 그 이외에 값을 넣으면 그냥 오류 메시지 발생
a = input("염기 서열을 입력해주세요: ")
b = {"a":0, "t":0, "g":0, "c":0} # 딕셔너리 b를 초기화

for i in a: # 문자열 a를 하나씩 읽어들임
  b[i] += 1 # 읽어들인 문자에 해당하는 키 값을 가진 b의 딕셔너리 값을 1 증가시킴

for j in b: # 딕셔너리 b에서 키 값을 하나씩 읽어들임
  print("{}의 개수 : {}".format(j,b[j])) # 키와 그에 해당하는 값(문자의 개수)을 출력
# 2번 문제 교수님 심화 // 대문자 입력 안 됨, 그 이외에 값을 넣으면 그냥 오류 메시지 발생 
# a,t,g,c 만 입력하게 하려면 그냥 인풋 설명에 입력하는게 좋음.
# 딕셔너리 생성 없이 함수 이용해서 해결
from collections import Counter # 자료의 개수를 셀 때 유용하게 사용됩니다.

# 사용자로부터 염기 서열을 입력받습니다.
a = input("염기 서열을 입력해주세요: ")

# Counter 클래스를 사용하여 각 문자의 개수를 세어서 딕셔너리 형태로 저장합니다.
b = Counter(a)

# 딕셔너리 b를 순회하며 각 문자의 개수를 출력합니다.
for j in b:
    print("{}의 개수 : {}".format(j, b[j]))

** 나

# 2번 문제 (염기의 개수) 268p // ATGC 이외의 값을 추가하면 출력 안되게끔
sequence = input("염기 서열을 입력하세요\n예)ATGCatgc \n")  # 사용자로부터 염기 서열을 입력받음
nucleotides = {'a':0, 't':0, 'g':0, 'c':0}  # 염기 서열에서 'a', 't', 'g', 'c'가 나올 때마다 개수를 저장할 딕셔너리 초기화

while True:  # 무한 루프
    valid = True  # 입력된 염기 서열이 올바른지 여부를 저장하는 변수
    for n in sequence:  # 입력된 염기 서열에서 각 염기를 반복
        if n.lower() in nucleotides:  # 염기가 'a', 't', 'g', 'c' 중 하나인지 확인
            nucleotides[n.lower()] += 1  # 염기의 개수를 1 증가
        else:
            valid = False  # 올바르지 않은 염기 서열임을 표시
            print("atgc 이외의 문자가 포함되어 있습니다.")
            sequence = input("다시 입력해주세요.\n")  # 올바른 염기 서열을 다시 입력받음
            nucleotides = {'a':0, 't':0, 'g':0, 'c':0}  # 염기 개수를 다시 초기화
            break  # 입력된 염기 서열에서 'atgc' 이외의 문자가 발견된 경우 루프를 종료하고 처음부터 다시 시작
    if valid:  # 입력된 염기 서열이 올바르면
        break  # 무한 루프를 종료하고 다음 코드를 실행

# 'a', 't', 'g', 'c'의 개수 출력
print("a의 개수 : {}".format(nucleotides['a']))
print("t의 개수 : {}".format(nucleotides['t']))
print("g의 개수 : {}".format(nucleotides['g']))
print("c의 개수 : {}".format(nucleotides['c']))

 

* 3번 문제 - 코돈의 개수

** 교수님 풀이

# 3번 문제 (코돈의 개수) // 교수님 풀이
a = input("염기 서열을 입력해주세요\n(염기서열 atgc만 입력해주세요):\n")  # DNA 서열을 입력받습니다.

b = {}  # 빈 딕셔너리를 생성합니다.

for i in range(0, len(a), 3):  # range 함수를 사용하여 a의 인덱스를 0부터 시작하며 3씩 증가시킵니다.
  c = a[i:i+3]  # 인덱스 i부터 i+3까지의 염기를 추출하여 c에 저장합니다.
  if len(c) == 3:  # 추출한 코돈이 3개의 염기로 이루어져 있다면, 코돈의 개수를 세는 작업을 진행합니다.
    if c in b:  # c가 b에 있는 키 값 중 하나인 경우, 해당 키의 값에 1을 더합니다.
      b[c] += 1
    else:  # c가 b에 없는 키인 경우, 새로운 키로 추가하고 값을 1로 설정합니다.
      b[c] = 1

print(b)  # b 딕셔너리를 출력합니다.

** 나

# 3번 문제 (코돈의 개수) 269p // 대소문자 구분없이 입력받고 ATGC 이외의 값을 추가하면 출력 안되게끔

codons = {}  # 빈 딕셔너리 생성

while True:
    sequence = input("염기 서열을 입력하세요\n(염기서열은 A,T,G,C입니다) \n")
    if set(sequence.upper()) - set('ATGC'):  # 입력값이 ATGC 이외의 문자를 포함하면 다시 입력 받음
        print("ATGC 이외의 문자가 포함되어 있습니다. 다시 입력해주세요.")
    else:
        break

sequence = sequence.upper()  # 입력값을 모두 대문자로 변환

i = 0
while i < len(sequence)-2:  # 염기서열의 마지막 세 자리를 제외한 모든 코돈을 추출함
    codon = sequence[i:i+3]
    if codon in codons:  # 추출한 코돈이 이미 딕셔너리에 있다면 값에 1을 더함
        codons[codon] += 1
    else:  # 딕셔너리에 코돈이 없다면 값을 1로 설정함
        codons[codon] = 1
    i += 3

print(codons)  # 코돈과 해당 코돈의 개수를 출력함

 

* 4번 문제 - 2차원 리스트 평탄화 270p

 

** 교수님

# 도전문제4
a = [1,2,[3,4],5,[6,7],[8,9]]
b = []
for i in a:
  if type(i) == list:
    for j in i:
      b.append(j)
  else:
    b.append(i)
print("{}를 평탄화하면 \n{}입니다.".format(a,b))

 

 

 

 

* 나

# 4번 문제 2차원 리스트 평탄화 270P
def flatten(lst):
    flattened = []  # 평탄화된 1차원 리스트를 저장할 리스트
    for elem in lst:  # 리스트의 원소들을 하나씩 순회
        if type(elem) == list:  # 원소가 리스트일 경우
            flattened.extend(flatten(elem))  # 재귀적으로 평탄화하여 flattened 리스트에 추가
        else:  # 원소가 리스트가 아닐 경우
            flattened.append(elem)  # flattened 리스트에 원소 추가
    return flattened  # 평탄화된 1차원 리스트 반환


a = [1,2,[3,4],5,[6,7],[8,9]]
b = flatten(a)

print("{}를 평탄화하면\n{}입니다".format(a,b))

 

 

* 정리

- 튜플은 값을 고정시키는 것이다.

 

 

* 핵심

주석 이해하면서 연습문제 꼭 풀어보기 

 

 

* 링크 (직접 글 쓴 당사자만 확인 가능 // 계정 이동해서 확인하기)

 

Google Colaboratory Notebook

Run, share, and edit Python notebooks

colab.research.google.com

 

 

728x90
반응형
LIST