[Tutor] lists, tuples, arrays

Magnus Lycka magnus@thinkware.se
Mon Feb 24 21:29:02 2003


At Mon, 24 Feb 2003 16:37:03 -0500, John Keck wrote:
>I'm a somewhat experienced programmer (though not necessarily with
>object-oriented code), but I'm having trouble understanding the differences
>between using lists, tuples, and arrays, and maybe vectors.

Ok. Lets forget half of these then... ;)

>Unforuntately the online documents I've seen have not been helpful.

Where have you looked?

It's probably also helful if you say something about
your background and what you are looking for. You seem
to be interested in mathematical manipulations of arrays.

>  Perhaps
>part of my frustration is that so much of how Python operates on these sorts
>of things is so unlike what I'm used to, and I have a perhaps unrealistic
>hope to do with Python what I can do so easily in, say, IDL or C.

You should expect that the things you do in C will be
easier to do in Python. Much more power, much less typing.
When you learn how to use Python effectively, which is not
entirely like C programming, you will be conciderably more
productive in Python than in C, but of course it takes some
time to get used to the different concepts. At least that's
my experience, and that of many others as well. See
http://www.ipd.uka.de/~prechelt/Biblio/jccpprt_computer2000.pdf
for an empirical study on the subject, or
http://www.thinkware.se/cgi-bin/thinki.cgi/PythonQuotes
for more subjective opinions.

If you are making up C-style solutions, they are probably
different than the optimal pythonic solution, but you will
see that in time.

It might be that you just don't see how easy it is,
since you are used to the convoluted ways of C... :)

>First of all, what are the basic differences between these different types?

Typically, you use a python list object in the cases where you
would use a list, vector or array in other languages.

There is not builtin vector or array type in Python. I don't
know why you mention these. There is an array module and an
array function in the Numeric package, but this is not part
of the core Python language. Numeric is not even a standard
module, although it's widely used in the scientific community.

A tuple is an immutable list, you might say. Once a tuple is
defined, it can't be changed. (Although if it contains mutable
objects, these might change.) Tuples are more light weight than
lists, and tuples containing only immutable objects are hashable,
so they can be used as keys in associative arrays (called
dictionaries in Python).

For instance, if we fetch data from a normal database table, where
each row always have the same number of elements, but where we
have a varying number of rows and might append or remove rows at
will, it would be natural to represent this as a list of tuples.

[(1, 'Magnus', 38),
  (2, 'Marius', 4),
  (3, 'Auste', 34)]

You will probably notice that python programmers often use tuples
where C programmers would use structs, but tuple elements are only
accessed by index, not by name.

Tuples are sometimes used without parenthesis as in:

 >>> a, b = 5, 1
 >>> print a, b
5 1
 >>> a, b = b, a + b
 >>> print a, b
1 6
 >>> a, b = b, a
 >>> print a, b
6 1

Lists and tuples can contain anything:

 >>> a = []
 >>> a.append(1) # integer
 >>> a.append(1+1j) # complex
 >>> a.append(3.14159) # float
 >>> a.append('Hello') # string
 >>> a.append(a) # itself
 >>> a.append(Numeric) # module
 >>> a.append(int) # type
 >>> print a
[1, (1+1j), 3.1415899999999999, 'Hello', [...], <module 'Numeric' from 
'G:\Python22\lib\site-packages\Numeric\Numeric.pyc'>, <type 'int'>]

 >>> t = tuple(a)
 >>> for e in t:
...     print e
...
1
(1+1j)
3.14159
Hello
[1, (1+1j), 3.1415899999999999, 'Hello', [...], <module 'Numeric' from 
'G:\Python22\lib\site-packages\Numeric\Numeric.pyc'>, <type 'int'>]
<module 'Numeric' from 'G:\Python22\lib\site-packages\Numeric\Numeric.pyc'>
<type 'int'>

Numeric arrays can only contain numeric stuff.

>For example, I'm trying to set all the values of a slice of a list (or
>array) to a particular value.  How do I do that?

Like this?

 >>> a = [7] * 10
 >>> a
[7, 7, 7, 7, 7, 7, 7, 7, 7, 7]
 >>> a[3:7] = [5]*4
 >>> a
[7, 7, 7, 5, 5, 5, 5, 7, 7, 7]

>Another example: I'm have a list (or array) of vectors.  How do I multiply
>all of them by a scalar?

If you really want to do matrix mathematics you might
want Numeric python after all, but I still think it's
better to get aquainted with the core language before
you mess with large third party modules.

In core python there are a few solutions. The simplest is
to make a loop more or less as in C:

 >>> l = range(5)
 >>> l
[0, 1, 2, 3, 4]
 >>> s = 5
 >>> r = []
 >>> for e in l:
...     r.append(s * e)
...
 >>> r
[0, 5, 10, 15, 20]

or inline

 >>> l
[0, 1, 2, 3, 4]
 >>> for i in range(len(l)):
...     l[i] *= s
...
 >>> l
[0, 5, 10, 15, 20]

There is also a more lisp style solution:

 >>> map(lambda x: x*s, l)
[0, 25, 50, 75, 100]

And list comprehension which is borrowed from Haskell:

 >>> [x * s for x in l]
[0, 25, 50, 75, 100]

Of course, Numeric handles array multiplication out of the box:

 >>> import Numeric
 >>> l = Numeric.arange(5)
 >>> l
array([0, 1, 2, 3, 4])
 >>> l * s
array([ 0,  5, 10, 15, 20])

>Another question: what is the difference between range() and arange()?

range is a built in function, which returns a range of integers
in the form of a normal list object.

 >>> help(range)
Help on built-in function range:
range(...)
     range([start,] stop[, step]) -> list of integers

     Return a list containing an arithmetic progression of integers.
     range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.
     When step is given, it specifies the increment (or decrement).
     For example, range(4) returns [0, 1, 2, 3].  The end point is omitted!
     These are exactly the valid indices for a list of 4 elements.

 >>> range(5)
[0, 1, 2, 3, 4]
 >>> range(5, 10)
[5, 6, 7, 8, 9]
 >>> range(5, 10, 3)
[5, 8]

arange is a function in the Numeric package, which returns a
Numeric array (not a list) with a range of integers.

 >>> import Numeric
 >>> help(Numeric.arange)
Help on built-in function arange:
arange(...)
     arange(start, stop=None, step=1, typecode=None)

      Just like range() except it returns an array whose type can be
     specified by the keyword argument typecode.

In numeric, the typical python flexibility is removed to assure that
we have homogenous data types and faster calculations.

 >>> arange = Numeric.arange
 >>> arange(5)
array([0, 1, 2, 3, 4])

Specify integers

 >>> arange(5, typecode='i')
array([0, 1, 2, 3, 4],'i')

Specify floats

 >>> arange(5, typecode='f')
array([ 0.,  1.,  2.,  3.,  4.],'f')


Perhaps you can describe a little more what you want to achieve.
It's ok to show C code, but don't expect the Python solution to
look like the C solution.


-- 
Magnus Lycka, Thinkware AB
Alvans vag 99, SE-907 50 UMEA, SWEDEN
phone: int+46 70 582 80 65, fax: int+46 70 612 80 65
http://www.thinkware.se/  mailto:magnus@thinkware.se