0

I'm a bit stumped on a python problem. I'd like to write a function that returns a list of all objects nested within a tuple.

For example I'd want to be able to turn the tuple (((2,4),6,(9,(3,7))) into [2,4,6,9,3,7]. However, I'm really unsure of how to start since tuples are immutable. Thanks!

Courtney
  • 69
  • 2
  • 9
  • 2
    Why does it matter that the tuple is immutable? You need to create a new list anyway. – Daniel Roseman Feb 27 '15 at 21:42
  • This isn't very practical but... my first thought was that I could use remove to take out the parenthesis. – Courtney Feb 27 '15 at 21:47
  • More like `for x in str(a).split(','): print x.strip("[]() {}")` ... but you're only getting string representations of the contents, which are not always the contents (e.g., declare a variable `foo` and put that in the tuple). – cphlewis Feb 27 '15 at 22:07
  • You're changing types anyways. So add to what Daniel Roseman said, don't worry about the fact that tuples are immutable. – notorious.no Feb 27 '15 at 22:08

4 Answers4

1

You need to flatten your tuple of tuple, see Flattening a shallow list in Python and the solution provided by James Brady:

def flatten(x):
    result = []
    for el in x:
        if hasattr(el, "__iter__") and not isinstance(el, basestring):
            result.extend(flatten(el))
        else:
            result.append(el)
    return result
Community
  • 1
  • 1
Nicolas Rougier
  • 670
  • 7
  • 15
  • Only returns names of dict items in the tuple, not that that's unreasonable. `a = ((1,2),5,((5,6)),345,['a','b',['c','d']],{'e':5,789:'s'})`. – cphlewis Feb 27 '15 at 21:57
0

Here's a good example of recursion - though Nicolas has a similar answer already.

Here we set up a the tuple you presented. We also setup an empty list for which you want the tuple in.

The function starts with the tuple and loops through each element. If the element is a tuple, it calls the function again, recursively until you get to a non-tuple. It then plugs that into the list.

tup = (((2,4),6,(9,(3,7))))
listversion = []
def loopthroughtup(tup):
    for i in tup:
        if type(i) == tuple:
            print str(i) + " is a tuple"
            loopthroughtup(i)
        else:
            print str(i) + " is not a tuple"
            listversion.append(i)

loopthroughtup(tup)
print listversion
fpes
  • 964
  • 11
  • 22
0

A very basic answer, but should do what you're asking. Uses try and except to see if the item is iterable. If True, then recurse the function, if False, add the item to the list.

iterable = (((2,4),6,(9,(3,7))))
_list = []


def addToList(elem, listRef):
    """
    elem: item you want to insert into the list
    listRef: list you want to append stuff to
    """
    try:
        for x in elem:
            addToList(x, listRef)    # recursive call
    except:
        listRef.append(elem)    # add the item if it's not iterable


# Main
for item in iterable:
    addToList(item, _list)    # iterate tuple, pass ea. element into addToList, pass the list you want to append to
print _list

Rule of thumb in Python, fail fast and fail cheap :)

Warning: If you have strings in the tuple, each char will be appended to _list (since strings are iterable). I didn't design around strings because you didn't specify whether you use them or not.

notorious.no
  • 4,919
  • 3
  • 20
  • 34
-2
from re import findall

a = ((143,243),534,((55,356)),645)
print findall('\d+', str(a))
# ['143', '243', '534', '55', '356', '645']

b = ((1,2),5,((5,6)),345)
print findall('\d+', str(b))
# ['1', '2', '5', '5', '6', '345']
Katpoes
  • 209
  • 1
  • 11