개발일기

TypeError: can only join an iterable 에러메세지 (feat. 프로그래머스 문자열 뒤집기, 특정 문자 제거하기 알고리즘) 본문

오류 및 알고리즘정리본

TypeError: can only join an iterable 에러메세지 (feat. 프로그래머스 문자열 뒤집기, 특정 문자 제거하기 알고리즘)

츄98 2023. 4. 5. 21:00

상황)

프로그래머스 문자열 뒤집기 알고리즘을 풀기 위해 다음과 같이 코드를 작성하였다.

def solution(my_string):
    list_string = list(my_string)
    return ''.join(list_string.reverse())
    # 문자열에는 reverse()가 안된다. 
    # reverse()는 리스트 타입 함수이기 때문에 사용하려면 문자열을 리스트로 변환해야 한다.
    # 그러므로 list() 사용해 리스트로 바꿔줌

이랬더니..? TypeError: can only join an iterable 에러메세지..!

 

또 프로그래머스 특정 문자 하나 제거하기 알고리즘을 풀기 위해 다음과 같은 코드를 작성했더니 똑같은 에러메세지 등장

def solution(my_string, letter):
   my_string_list = list(my_string)
   return ''.join(my_string_list.remove(letter))

 

 


iterable이란 무엇일까?

대표적으로 list, dict, set, str, bytes, tuple, range가 iterable한 타입들이다.

 

'구분자'.join( ) 살펴보기

문자로 이루어진 iterable 객체를 하나의 문자열로 만들 수있다.
구분자로 문자를 연결하여 하나의 문자열로 만든다. 

 

reverse( ) 살펴보기

reverse()는 list타입에서 제공하는 함수이다. 리스트의 요소를 뒤집는 함수이다. 

 

remove( ) 살펴보기

remove()는 array의 요소를 삭제한다. 괄호( ) 안에 삭제하고자 하는 값을 입력한다.
단, array 안에서 삭제하고자 하는 값이 여러 개가 있다 하더라도 첫 번째 값에 대해서만 삭제한다. 
remove() raises ValueError when x is not found in s ..
무슨 말이냐면, 삭제하고자 하는 값이 없을 경우 ValueError을 일으킨다.

 

 


원인은?

The error is caused because the reverse() method mutates the original list in place and doesn't return anything (implicitly returns None).

def remove(self, __value: _T) -> None

이것이 무슨 말인고 하니..! reverse(), remove()는 원래 리스트 자체를 변화시키지만, 리턴값으로 None을 리턴한다.

즉 값을 반환하지 않는다.

 

진짠가.. 직접 해봄.

num = [0,1,2,3,4,5]
new_list = num.reverse()
print(new_list)  # 👉️ None

정말 None으로 리턴이 된다.

리스트로 리턴되는 것이 아니었기 때문에, join을 바로 하면 에러메세지가 나왔던 것..!

 

 

 


해결방법은?

# 문자열 뒤집기
def solution(my_string):
    my_list = list(my_string)
    my_list.reverse()
    return ''.join(my_list)
    
# 특정문자 하나 제거하기
def solution(my_string, letter):
   my_string_list = list(my_string)
   my_string_list.remove(letter)
   return ''.join(my_string_list)

이렇게..  my_list.reverse()를 하고나서 join(my_list)를 하면 된다..!

join() 안에 바로 my_list.reverse()를 하게 되면, None을 join하는 것이 되어서 에러메세지가 나오므로,

이 점에 유의해서 코드를 작성해야 한다.

 

remove() 역시 마찬가지이다.

 

추가로..! Sort( ) 경우도 알아보기

reverse(), remove() 뿐만 아니라 sort() 역시 리턴값이 None이므로 (값을 반환하지 않는다.)

reverse, remove와 마찬가지로 유의해서 사용하자.

 

sort() 메소드는 리스트를 정렬된 상태로 변경한다.

sort() 역시 리스트 자체를 바꿔버리고, 리턴값이 None 이므로 join() 안에 바로 넣어버리면 에러메세지가 나온다.

Assigning a variable to the result of calling a built-in function that doesn't return anything (e.g. reverse, sort, etc).
직접 해보면..
num = [1,2,3,4,5,6]
print(num.sort(reverse = True)) #👉️ None

해결방법은 reverse, remove와 똑같다.

 

 


(문자열 뒤집기 알고리즘 다른 풀이 방법)

def solution(my_string):
    return my_string[::-1] # [::] 문자열도 가능! 역순으로 배열하라는 말~


def solution(my_string):
    my_list = reversed(my_string) #reversed는 파이썬 내장 함수라 문자열에게도 가능
    return ''.join(my_list)

 

(특정 문자 제거하기 알고리즘 풀이 방법)

# 특정문자 제거하기(모두...)
def solution(my_string, letter):
    my_string_list = list(my_string)
    while letter in my_string_list:
        my_string_list.remove(letter)
    return ''.join(my_string_list)

# 다른 사람 풀이
def solution(my_string, letter):
    return my_string.replace(letter, '')

def solution(my_string, letter):
    return ''.join([c for c in my_string if c != letter])