본문 바로가기
python

2020.08.19 알고리즘_k번째수

by 해맑은 코린이 2020. 8. 20.

2020.08.19 k번째 수 알고리즘 정리노트__

출처 - 프로그래머스

블로그를 시작하는 날짜이니 특별히 2개 올린다.. 의지 꺾이지마라 ..

오늘은 카페에서 에어컨 빵빵하게 틀었으니 예전부터 미뤘던 k번째 수도 머리에 머리를 굴려서... 드디어풀었따.

맨 처음에 문제 이해하는 것도 몇시간이 걸렸다... 그래서 정리해보려고 나혼자 주어진 i,j,k라도  프린트해서 명확하게 알아보자..라는 그게 컸다. 

그래서 나온 결과는 commands에 들어있는 3개의 리스트 중 하나를 따로 뺐고, 그 중 k를 프린트한 것이다.

근데 여기서 잠깐 none이 왜 왜나온 것일까..?

 

이것은 또 아직 기초가 부족한 나의 멍청한 짓이다.

여기서 print와 return의 차이를 다시 명확히 짚고 넘어가자(나혼자)

위 코드와 밑의 코드의 차이점을 보면 함수를 프린트 할 때 프린트를 쓰지 않았다. 

위와 차이점이 뭘까?

간단하다. 이 함수 자체 안에서 내가 print라는 기능을 내장해서 함수를 써줬기 때문이다. 

결국 내가 보고 싶은 수를 이미 프린트 기능을 하도록 함수를 짰는데 함수 통째로 다시 프린트를 해준다면 리턴값, 즉 반환하는 값이 없기 때문에 반환값이 없어! 하고 none 값을 프린트해 주는 것이지 으이구 바보


여기서 알아보는 print와 return의 차이

print  우리가 눈에 보일 수 있게 말그대로 출력해서 보여주는 것이다. 그냥 당장 변수를 보여줘라 뭐라도 출력해서 글자로 내 눈에 보이게 해 이런 느낌.

return 말그대로 반환값. 얘는 함수를 어떻게 짜냐에 따라 당장 눈에 보이지 않는다. 하지만 내가 짠 기능에 따라 함수는 돌아가고 있다. 위에 어떻게 짜냐에 따라 결과 값이 보여질수도 있고 안보여질수도 있는거라고 생각하면 쉬울거 같다...(그래놓고 항상 또 헷갈리겠지)  리턴은 그래서 꼭 적어줄 필요가 없다. 그냥 기능에 따라 항상 변하는 변환값인 셈. 하지만 동작은 함수에 따라 항상 하고 있다.. 제대로 짠 코드라면..(위에 프린트에서 그럼 안써줘도 된다고 했는데 왜그럼 none 이뜬거냐고 물으신다면 없는 값을 강제로 눈에 보이게 출력해줬기 때문)

쨋던 print를 빼주면 이렇게 이쁘게 출력된다.


다시 알고리즘 문제로 돌아와주자.

저렇게 commands에 있는 리스트 중 첫번째에서 문제에서 주어진 i,j,k를 따로 빼서 생각해보니 조금 감이 잡히는 것 같아 

복잡하기만 하고 쓸모가 없습니다.. 지나가셔도 좋습니다..

갑자기 급 복잡해졌다. 그래서 중간중간 프린트를  통해 결과를 보도록 하자.

위 3개는 분명 프린트가 잘 된 것을 볼 수 있다. 하지만 마지막 프린트가 오류가 났다. 

list indices must be integers or slices, not list

-해석하면 리스트는 인덱싱할 수 없다. 정수 즉, 숫자로 만들어줘라. 

int라는 파이썬 내장 함수는 문자열에만 쓸 수 있기 때문에 탈락.

그리고 나는 또 이 함수의 치명적 단점을 하나 보게 된다. 

ㅎ... 리스트가 담겨있던 commands 매개변수의 길이가 50개까지 있을 수 있다고 한다.

만약 commands 안에 담겨 있는 리스트가 50개라면 나는 array_list 와 num_list를 50개써줘야 한다..

뭐 변명같지만 위에는 문제 자체가 내 기준 이해가 안되어서.. 주욱 나열하면서 감을 잡으면서 풀어보려고 나름 짠 코드라서 무시해도 된다..그마저도 마지막은 실패했지만..

 

자 이제 그러면 불특정한 길이에는 어떻게 해야할까!

내가 알고리즘을 풀면서 for문을 안쓸리가 없지 for문을 돌려보자.

일단 우리가 리스트 모음인 commands를 for문 반복문을 통해서 돌려보았다.

하나씩 잘 프린트 된다. 그럼.. 우리가 할 일은 여기서 i,j,k를 잘 사용해서 알고리즘이 원하는 값을 주면 된다.

근데 아까 처럼 리스트로 나오게 되면.. 숫자형이 아니라서 슬라이싱을 사용할 수 없다..

그래서 하나씩 아예 처음부터 숫자로 정의해주었다..^^

최종 내 답을 풀이하자면,

commands 라는 리스트 모음을 리스트 하나하나 for문으로 분리해준다.

i는 i번째 숫자가 필요하기 때문에 0부터 숫자를 세기 시작하는 파이썬 리스트에서 -1을 빼서 내가 원하는 숫자로 슬라이싱을 통해 만들어 주었고, 

j는 [첫번째 숫자 : 끝 숫자 ] = [첫번째 숫자 : 끝 숫자-1] 만큼 리턴하는 파이썬 리스트의 특징으로 -1을 빼지 않아도 j 전의 수까지 리턴하기 때문에 마이너스 없이 써주면 된다. 

마지막 k는 i와 마찬가지로 0부터 세는 파이썬 리스트의 특징으로 -1을 빼서 내가 원하는 k번째의 수로 만들어 주었다.

 

그렇게 i번째부터 j번째까지 슬라이싱한 array를 sorted로 정렬해준다. -- 정렬하라고 문제에 써있음.

여기서 하나 더 짚고 가기.

 


sort와 sorted의 차이

 

sort() - 만약,

           a=[1,3,2,4,5]

           b = a.sort() 

           를 하게 되면, b에는 아무것도 담기지 않고, 내가 바꾸고자 하는 a 자체가 바뀌게 된다. 그래서 오류가 잘난다.

           그래서 b를 따로 써주지 않아도 된다. 왜냐? a자체가 바뀐거기 때문에 !

           

sorted() - 위의 예를 들어서 설명하면,

               a=[1,3,2,4,5]

               b= sorted(a)

               라고 하게 되면, a는 그대로 [1,3,2,4,5] 가 보존 되고, b 라는 변수에 정렬이 된 [1,2,3,4,5] 가 담기게 된다.

               그래서 오류도 덜 나고 구분하기도 쉽다!


 

쨋든쨋든 그래서 정렬해준 array_list에서 k번째 숫자를 슬라이싱해준 result_list를 만들어주고 

for문으로 여러 리스트를 돌렸기 때문에 각각의 k값을 담아주는 result라는 빈 리스트에 담아주는 append함수를 써주었다. 

또 마지막으로 하나 더 tmi


append 와 += 의 차이

 

append - 리스트에서 원소를 추가 할 때 쓰는 함수.

+= - 문자열과 숫자열에 보통 쓰이지만, 리스트에도 쓸 수는 있다. 그냥 더하기 사칙연산이라고 생각하믄 된다.

       쓰는 방법 차이이다.


이렇게 간단하게 다시 또 기초를 ... 다지는 나... 지금도 사실 항상 프린트해보고 오류 뜨면 아 그랬지 하면서 문제를 푼다...

 

그래서 알고리즘 마무리로 result를 리턴해주면!!!!!!!

언제봐도 짜릿한 정답입니다!!!!!!

흑흑 며칠간 게을러서 생각을 멈췄었는데 아까 알고리즘이 조금 일찍 끝나서 머리를 데굴데굴 굴렸다...

결국 풀어서 너므 기쁘다..이것도 몇만명이 다들 쉽게 푸셨던데 나는 정말..오래걸렸다..

 

++++추가 

출처 - 런치블로그

내가 자주 보는 블로그에서 어떤분은 lamda함수와 map함수를 써서 공부할겸 끄적끄적...

 

map

map 함수는 원본리스트를 해치지 않고 리스트 안 요소를 지정된 함수로 처리해주는 함수!

list(map(함수,리스트)) 보통 이런 형태로 쓰게 되는데

구글링을 해보니

[1.2,3.4,5.5] 같은 정수가 아닌 것들의 리스트나 

["1","3","5"] 같은 문자열의 리스트를 정수형으로 변환 시켜줄 때 주로 쓰이는 것 같다. 그 외에도 활용도는 다양하겠지만.. 다음에 써서 또 정리해볼테다. 오늘은 무슨 기능을 하는지만 대충 정리!

 

맨날 나같은 경우는 for문을 써서 각각 int - 정수로 바꿔주는 함수 로 변환해서 만들어 주었는데,

list(map(int,[1.2,3.4,5.5])

이렇게 하면 map을 사용하여 정수형으로 바꿔준 요소들을 다시 리스트에 담아줘서 [1,3,5]로 바뀐다 !

이와 같이 str 쓰면 문자열로 리스트 안 요소들을 바꿔주게 된다. 

 

 

lamda

 

람다라고 읽는 이 것은 def 처럼 함수의 역할을 한다.

하지만 한줄로 표현할 수 있고, 간단하게 return값이 없어도 결과값을 보여준다는 것이 특징이다.

예를 들어,

plus = lambda a, b: a+b 

print(plus(2,3))

을 해주게 되면 6이 출력된다. 

 

 

사실 간단하게 정리하고 좀 더 들어가니 어렵... 다음에 좀 더 자세하게 공부해봐야겠다.. 오늘은 느낌만 알고 정리정리! 

 

 

 

 

 

 

 

 

댓글