1

How can I get the max over all elements in a tuple of tuples?

Example:

x = ((3, 4, 5), (4.5, 5.5, 6.5), (-1, 0, 1, 10))
# want 10
Frank
  • 64,140
  • 93
  • 237
  • 324
  • As related info, how can I generally flatten a list, such that `flatten(x) = (3, 4, 5, 4.5, 5.5, 6.5, -1, 0, 1, 10)`? – Frank Apr 29 '13 at 00:07

5 Answers5

5

Using itertools.chain and max():

In [93]: from itertools import chain

In [94]: max(chain(*x))
Out[94]: 10

or using chain.from_iterable:

In [97]: max(chain.from_iterable(x))
Out[97]: 10

Creating a flat list:

In [101]: list(chain.from_iterable(x))
Out[101]: [3, 4, 5, 4.5, 5.5, 6.5, -1, 0, 1, 10]

In [102]: list(chain(*x))
Out[102]: [3, 4, 5, 4.5, 5.5, 6.5, -1, 0, 1, 10]

These itertools methods are highly efficient in comparison to other alternatives.

Related: Flattening a shallow list in Python

Community
  • 1
  • 1
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
5

If you are a why-import-when-I-can-do-it-myself kinda guy, I suggest:

>>> x = ((3, 4, 5), (4.5, 5.5, 6.5), (-1, 0, 1, 10))
>>> max(max(t) for t in x)
10

To flatten a tuple of tuples:

>>> tuple(elem for t in x for elem in t)
(3, 4, 5, 4.5, 5.5, 6.5, -1, 0, 1, 10)

or

>>> sum((t for t in x), ())
(3, 4, 5, 4.5, 5.5, 6.5, -1, 0, 1, 10)
juliomalegria
  • 24,229
  • 14
  • 73
  • 89
  • 1
    Python docs suggest that we should prefer `itertools` for flattening rather than using `sum`. http://docs.python.org/2/library/functions.html#sum – Ashwini Chaudhary Apr 29 '13 at 00:23
  • @AshwiniChaudhary Suggestion is made because `itertools.chain` returns a generator instead of creating a new list/tuple. If you're going to make a `list` out of it, both alternatives are pretty much the same. – juliomalegria Apr 29 '13 at 00:32
  • No they are not same, `itertools.chain` and `chain.from_iterable` are highly efficient in comparison to both generator expression and `sum`. – Ashwini Chaudhary Apr 29 '13 at 00:44
3

One more option, along the lines of the nested for loop:

max(max(i) for i in x)
1

You could use a nested for loop:

In [9]: max(n for s in x for n in s)
Out[9]: 10

And to flatten an arbitrarily nested list, you could use a recursive function:

def flatten(lst):
    for item in lst:
        if isinstance(item, (tuple, list)):
            for result in flatten(item):
                yield result
        else:
            yield item
Blender
  • 289,723
  • 53
  • 439
  • 496
0

You could convert the tuple into a single tuple with all of the elements, and then iterate over that ( or use the built in method max() ). This also answers your question of how to 'flatten' the tuple.

a_tuple = ((1, 2, 3), (5, 6, 7), (8, 9))

tuple_to_string = str(a_tuple)

After converting it to a string, remove the "(", ")", and any spaces " ", then use join to convert it into a single list, and then tuple() to convert it back into a tuple.

altered_string = tuple_to_string.replace("(", "").replace(")", "").replace(" ", "")
>> "1,2,3,5,6,7,8,9"
flattened_tuple = tuple(altered_string.split(","))
>> ('1', '2', '3', '5', '6', '7', '8', '9')

All in one line, then:

flattened_tuple = tuple(str(a_tuple).replace("(", "").replace(")", "").replace(" ", "").split(","))
>> ('1', '2', '3', '5', '6', '7', '8', '9')

To find the highest number, then use:

max(flattened_tuple)
>> 9

Take note that doing it this way will convert any elements inside of the tuple to a string. If you want them to come out the same, you'll have to do further formatting. For this purpose alone, though, this works just fine.

chrisvans
  • 238
  • 2
  • 8