1

Without any heavy libraries such as numpy, I want to uniformly handle a single list or multi-dimensional list in my code. For example, the function sum_up(list_or_matrix) should return 6 for argument [1, 2, 3] and return 9 for [[1, 2, 3], [1, 2, 0]].

My question is: 1. Can I code in a way without explicitly detecting the dimension of my input such as by isinstance(arg[0], (tuple, list))?

2. If I have to do so, is there any elegant way of detecting the dimension of a list (of list of list ...), e.g. recursively?

dolaameng
  • 1,397
  • 2
  • 17
  • 24

5 Answers5

1

As many users suggested you can always use dict instead of list for any-dimensinal collection. Dictionaries are accepting tuples as arguments as they are hashable. So you can easy fill-up your collection like

>>> m = {}
>>> m[1] = 1
>>> m[1,2] = 12
>>> m[1,2,"three",4.5] = 12345
>>> sum(m.values()) #better use m.itervalues() in python 2.* 
12358
Community
  • 1
  • 1
Odomontois
  • 15,918
  • 2
  • 36
  • 71
  • In this case, is there a straight way of telling the dimension of the data structure like the shape of the numpy array? for example, the dim of {0: 1, 1: 2} should be 2, and {(0, 0): 1, {0,1}: 2, {1,0}: 1, {1,1}: 2} should be (2, 2) – dolaameng Feb 28 '12 at 03:59
  • set( len(dim) for dim in m if isinstance(dim,tuple)) will give you set of possible shapes for all items, having tuple key – Odomontois Feb 28 '12 at 04:28
  • yes, actually using the set may be an overkill? for the multi-dimensional keyed dict, i was thinking of using (dim + 1 for dim in max(data.keys())) thanks! – dolaameng Feb 28 '12 at 04:48
1

You can solve this problem using recursion, like this:

#!/usr/bin/env python

def sum(seq_or_elem):
  if hasattr(seq_or_elem, '__iter__'):
    # We were passed a sequence so iterate over it, summing the elements.
    total = 0
    for i in seq_or_elem:
      total += sum(i)
    return total
  else:
    # We were passed an atomic element, the sum is identical to the passed value.
    return seq_or_elem

Test:

>>> print(sum([1, 2, [3, [4]], [], 5]))
15
Marc Cohen
  • 3,742
  • 2
  • 19
  • 19
0

Well I dont see a way if you are planning to use a single function to sum up your list like sum_up(list_or_matrix).

If you are having a list of lists I would only imagine you need to loop through the list to find out if its a 1-D or a 2-D list. Anyway whats wrong in looping?

def sum_up(matrix):
    2DMatrix = False
    for item in matrix:
        if type(item) == list:
            2DMatrix = True

    if(2DMatrix):
        //sum 2d matrix
    else:
        //sum 1d matrix
Srikar Appalaraju
  • 71,928
  • 54
  • 216
  • 264
0

You could sum recursively until you have a scalar value:

def flatten(x):
    if isinstance(x, list):
        return sum(map(flatten, x))
    return x

Note: you can use collections.Iterable (or another base class) instead of list, depending on what you want to flatten.

strcat
  • 5,376
  • 1
  • 27
  • 31
0

A simple way to sum up a matrix is as follow:

def sum_up(matrix):
    if isinstance(matrix, (tuple, list)):
        return sum(matrix)
    else:
        return sum((sum(x) for x in matrix))

The 'else' branch uses list comprehension, a powerful and quick tool.

Zenon
  • 1,481
  • 12
  • 21