2

I have a tuple, which consists of some tuple of integers and some integers, like ((1, 2), 3, (4, 5), 6).Now I need all integers from it. I wrote:

def get_all_items(iterable):
    t = []

    for each in iterable:
        if type(each) == int:
            t.append(each)
        else:
            t.extend(each)

    return tuple(t)

It works for me. Is there any better way to do this?

hola
  • 930
  • 1
  • 17
  • 35
  • 1
    Do you know for sure that there is only one level of hierarchy, i.e., you don't have a tuple of tuples of tuples? – Kyle Strand Oct 15 '13 at 03:23

5 Answers5

3

Don't forget the cheats way

>>> from ast import literal_eval
>>> t = ((1, 2), 3, (4, 5), 6)
>>> literal_eval(repr(t).translate(None, '()'))
(1, 2, 3, 4, 5, 6)
John La Rooy
  • 295,403
  • 53
  • 369
  • 502
1
from itertools import chain

def flatten(items):
  def renest():
    for item in items:
      try:
        yield iter(item)
      except TypeError:
        yield iter([item])
  return list(chain.from_iterable(renest()))
kojiro
  • 74,557
  • 19
  • 143
  • 201
1

I think your way is fine. Here's another way, using recursion, which will work for an arbitrarily-deeply-nested iterable structure:

def get_all_items(iterable):
    try:
        result = []
        for element in iterable:
            result += detuple(element)
        return result
    except TypeError:
        return [iterable]

Also, it may be useful to know that the operation you're describing is known as "flattening" a data structure.

Brionius
  • 13,858
  • 3
  • 38
  • 49
1
import itertools
itertools.chain.from_iterable(
    item if hasattr(item, '__iter__') else (item,)
        for item in iterable 
)
Leonardo.Z
  • 9,425
  • 3
  • 35
  • 38
1

You can simplify your code like this

def get_all_items(iterable):
    t = []
    for each in iterable:
        t.extend(list(each) if isinstance(each, tuple) else [each])
    return tuple(t)

print get_all_items(((1, 2), 3, (4, 5), 6))

Output

(1, 2, 3, 4, 5, 6)
thefourtheye
  • 233,700
  • 52
  • 457
  • 497