Pythonic solution to display multi-dimensional tuple as a tree
Neither the code provided in the question or the top voted answer work correctly. This is as you're making unreasonable assumptions on how the data is formed.

&gt;&gt;&gt; print(showtree('(A)'))
└─A
&gt;&gt;&gt; print(showtree('(1, ((2)), (3, 4, (5)))'))
┬─1
├─┬─└─2
├─┬─3
│ ├─4
│ ├─└─5
&gt;&gt;&gt; print(tree_string_to_display_string('(1, ((2)), (3, 4, (5)))'))
┬─1
├─┬─└─2
├─┬─3
│ ├─4
│ ├─└─5


Your code is also doing two things at once, parsing a string and building a tree. And so I will only take a tuple as input. If you need to take a string then you can build the parser separately.


Make the code work with one item.

To do this should be fairly simple, we take the tuple ('1',) and return ──1.

def build_tree(root):
    return '\n'.join(_build_tree(root))


def _build_tree(node):
    yield '──' + node[0]


&gt;&gt;&gt; print(build_tree(('1',)))
──1

Make the code work with 1, 2 or more items.

This is fairly simple, we check node's length and use the above code if it's 1. Otherwise we make:


The first item start with ┬─.
The last item start with └─.
All other items start with ├─.


This is as simple as using tuple unpacking, and then iterating over the middle.

def _build_tree(node):
    if len(node) == 1:
        yield '──' + node[0]
        return

    start, *mid, end = node
    yield '┬─' + start
    for value in mid:
        yield '├─' + value
    yield '└─' + end


&gt;&gt;&gt; print(build_tree(('1',)))
──1
&gt;&gt;&gt; print(build_tree(('1', '2')))
┬─1
└─2
&gt;&gt;&gt; print(build_tree(('1', '2', '3')))
┬─1
├─2
└─3

Get the code to work if you only enter a value, no tuples.

This is simple, since we're only allowing tuples as the nesting datatype, then we can just add an if not isinstance(node, tuple). We will convert this to a string now to help our future selves.

def _build_tree(node):
    if not isinstance(node, tuple):
        yield str(node)
        return

    if len(node) == 1:
        yield '──' + node[0]
        return

    start, *mid, end = node
    yield '┬─' + start
    for value in mid:
        yield '├─' + value
    yield '└─' + end


&gt;&gt;&gt; print(build_tree('1'))
1

Get the code to work recursively with the same input as (2). To check this we will change the input to integers.

This is simple. We run _build_tree on all the values in node, if it's a tuple. From here we only work on these values. We know these values are going to be iterators with only one value. This means we can just use next for now.

def _build_tree(node):
    if not isinstance(node, tuple):
        yield str(node)
        return

    values = [_build_tree(n) for n in node]
    if len(values) == 1:
        yield '──' + next(values[0])
        return

    start, *mid, end = values
    yield '┬─' + next(start)
    for value in mid:
        yield '├─' + next(value)
    yield '└─' + next(end)


&gt;&gt;&gt; print(build_tree((1,)))
──1
&gt;&gt;&gt; print(build_tree((1, 2)))
┬─1
└─2
&gt;&gt;&gt; print(build_tree((1, 2, 3)))
┬─1
├─2
└─3

Get the code working recursively.

We know all the current yields work the same way, and so this calls for a new function. This should take three values:


The value to add to the first item. (This is what we're doing right now)
The value to add on all other items.
This is important as if a node is only one large. But has nested data that is larger than one value then we will add '  ' to the output.
The nested data.


This is really simple to build:

def build_lines(first, other, values):
    yield first + next(values)
    for value in values:
        yield other + value


Finally we adjust the current yields so they are yield from functions.


def build_tree(root):
    return '\n'.join(_build_tree(root))


def _build_tree(node):
    if not isinstance(node, tuple):
        yield str(node)
        return

    values = [_build_tree(n) for n in node]
    if len(values) == 1:
        yield from build_lines('──', '  ', values[0])
        return

    start, *mid, end = values
    yield from build_lines('┬─', '│ ', start)
    for value in mid:
        yield from build_lines('├─', '│ ', value)
    yield from build_lines('└─', '  ', end)


def build_lines(first, other, values):
    yield first + next(values)
    for value in values:
        yield other + value


&gt;&gt;&gt; print(build_tree(('01', ('02',  '03', '04'), '05', (('06', '07'), '08'), ('09', ('10', '11'), ('12', '13'), '14'), '15')))
┬─01
├─┬─02
│ ├─03
│ └─04
├─05
├─┬─┬─06
│ │ └─07
│ └─08
├─┬─09
│ ├─┬─10
│ │ └─11
│ ├─┬─12
│ │ └─13
│ └─14
└─15
&gt;&gt;&gt; print(build_tree(('A', 'B multi-word item', ('C', 'D'), ('E', '', 'F'), 'G')))
┬─A
├─B multi-word item
├─┬─C
│ └─D
├─┬─E
│ ├─
│ └─F
└─G
&gt;&gt;&gt; print(build_tree((1, ((2,),), (3, 4, (5,)))))
┬─1
├─────2
└─┬─3
  ├─4
  └───5