Skip to content

How to Resolve "TypeError: can only join an iterable" in Python

Fix the Python TypeError: can only join an iterable when str.join() receives None or non-iterable values like lists modified in-place or missing return statements.

The error TypeError: can only join an iterable occurs when you call the str.join() method with a non-iterable value as its argument. The join() method requires an iterable (like a list, tuple, or set) of strings.

This guide explains the error and provides the correct ways to use join().

Understanding str.join() and Iterables

The str.join() method is used to concatenate strings from an iterable into a single string, using the string on which join() is called as a separator. An iterable is any object that can be looped over, such as:

  • Lists: ['apple', 'banana', 'cherry']
  • Tuples: ('apple', 'banana', 'cherry')
  • Sets: {'apple', 'banana', 'cherry'} (order is not guaranteed)
  • Strings: 'apple' (iterates over characters)
  • Dictionary keys: my_dict.keys() (iterates over keys)
  • Dictionary values: my_dict.values() (iterates over values)
  • Dictionary items: my_dict.items() (iterates over (key, value) tuples)
  • Generators: (x for x in range(5))

Incorrect Usage:

Correct Usage:

my_str = ','.join(['apple', 'banana', 'cherry'])  # List (iterable)
print(my_str)  # Output: apple,banana,cherry

my_str = '-'.join(('a', 'b', 'c')) # Tuple (iterable)
print(my_str) # Output: a-b-c

my_str = ''.join({'x', 'y', 'z'}) # Set (iterable, but order not guaranteed)
print(my_str)  # Output: (order is not guaranteed)

Common Causes of the Error

Passing None to join()

The most frequent cause is accidentally passing None to join():

my_list = None  #  Could be the result of a function call, etc.

Common Sources of None

  • Functions that don't return a value: A function that has no explicit return statement implicitly returns None. If you call such a function and pass its result to join(), you'll get the error.

    def get_list():
        print(['kiwi', 'banana', 'apple'])
    • The function needs to return an iterable for it to work.
      def get_list():
          return ['kiwi', 'banana', 'apple']
      my_str = ' '.join(get_list())
      print(my_str) # Output: kiwi banana apple
  • Methods that modify in place: Many list methods (like sort(), reverse(), append()) modify the list in place and return None.

    fruits = ['kiwi', 'banana', 'apple']
    new_list = fruits.reverse()
    print(new_list)  # 👉️ None
    • You must first call the method to modify the list, and then pass the list object to the join() function.
  • Conditional returns: A function might return a list only under certain conditions, and None otherwise.

    def get_list(a):
        if len(a) > 3:
            return a
    • You must always make sure to return an iterable.

Passing a Non-Iterable Value

Passing any value that is not an iterable, like an integer, a boolean or a single string, will cause the error:

Solutions and Best Practices

Always Pass an Iterable

The fundamental solution is to always ensure you're passing an iterable of strings to join(). If you're unsure, use isinstance() to check:

my_variable = ['a', 'b', 'c']  # Could be anything

if isinstance(my_variable, (list, tuple, set, str)): # Check if it is a sequence
    result = ','.join(my_variable)
    print(result)
else:
    print("Error: my_variable is not iterable")
  • isinstance(my_variable, (list, tuple, set, str)): This checks if my_variable is an instance of any of the listed types. This is a good, robust check.

Checking for None Before Joining

If your variable might be None, check for that before calling join():

my_list = None  # Or some function that might return None

if my_list is not None:
    result = ','.join(my_list)
    print(result)
else:
    result = "" # Or some other default
    print("my_list was None. Using empty string.")


result = ','.join(my_list) if my_list is not None else ''

Ensure Functions Return Iterables

If you're calling a function that's supposed to return a list (or other iterable), make sure it always does, even in error cases:

def get_items():
    try:
        return ['item1', 'item2', 'item3']
    except SomeError:
        print("An error occurred!")
        return []  # Return an EMPTY LIST on error, not None
result = ', '.join(get_items()) # safe

Conclusion

The TypeError: can only join an iterable error in Python is a clear indication that you're using str.join() incorrectly.

  • Always pass an iterable of strings to join().
  • If there's a possibility of None, check for it explicitly.
  • If a function is supposed to return an iterable, make sure it always does so, even in error cases.

By following these guidelines, you can avoid this common error and write more reliable Python code.

Navigation