Python arrays and sting formatting options

Discussion in 'Python' started by Ivan Reborin, Sep 29, 2008.

  1. Ivan Reborin

    Ivan Reborin Guest

    Hello everyone,

    I was wondering if anyone here has a moment of time to help me with 2
    things that have been bugging me.

    1. Multi dimensional arrays - how do you load them in python
    For example, if I had:
    -------
    1 2 3
    4 5 6
    7 8 9

    10 11 12
    13 14 15
    16 17 18
    -------
    with "i" being the row number, "j" the column number, and "k" the ..
    uhmm, well, the "group" number, how would you load this ?

    If fortran90 you would just do:

    do 10 k=1,2
    do 20 i=1,3

    read(*,*)(a(i,j,k),j=1,3)

    20 continue
    10 continue

    How would the python equivalent go ?

    2. I've read the help on the next one but I just find it difficult
    understanding it.
    I have;
    a=2.000001
    b=123456.789
    c=1234.0001

    How do you print them with the same number of decimals ?
    (eg. 2.000, 123456.789, 1234.000)
    and how do you print them with the same number of significant
    decimals?
    (eg. 2.000001, 123456.7, 1234.000 - always 8 decimals) ?


    Is something like this possible (built-in) in python ?

    Really grateful for all the help and time you can spare.

    --
    Ivan
    Ivan Reborin, Sep 29, 2008
    #1
    1. Advertising

  2. Ivan Reborin

    Mensanator Guest

    On Sep 29, 5:04 pm, Ivan Reborin <>
    wrote:
    > Hello everyone,
    >
    > I was wondering if anyone here has a moment of time to help me with 2
    > things that have been bugging me.
    >
    > 1. Multi dimensional arrays - how do you load them in python
    > For example, if I had:
    > -------
    > 1 2 3
    > 4 5 6
    > 7 8 9
    >
    > 10 11 12
    > 13 14 15
    > 16 17 18
    > -------
    > with "i" being the row number, "j" the column number, and "k" the ..
    > uhmm, well, the "group" number, how would you load this ?
    >
    > If fortran90 you would just do:
    >
    > do 10 k=1,2
    > do 20 i=1,3
    >
    > read(*,*)(a(i,j,k),j=1,3)
    >
    > 20 continue
    > 10 continue
    >
    > How would the python equivalent go ?
    >
    > 2. I've read the help on the next one but I just find it difficult
    > understanding it.
    > I have;
    > a=2.000001
    > b=123456.789
    > c=1234.0001
    >
    > How do you print them with the same number of decimals ?
    > (eg. 2.000, 123456.789, 1234.000)


    >>> print '%0.3f' % 2.000001

    2.000
    >>> print '%0.3f' % 123456.789

    123456.789
    >>> print '%0.3f' % 1234.0001

    1234.000


    > and how do you print them with the same number of significant
    > decimals?
    > (eg. 2.000001, 123456.7, 1234.000 - always 8 decimals) ?


    Your examples are 7 decimals (and you're not rounding).

    Here's what 8 looks like (note that it's %0.7e because there
    is always one digit to the left of the decimal point.)

    >>> print '%0.7e' % 2.000001

    2.0000010e+00
    >>> print '%0.7e' % 123456.789

    1.2345679e+05
    >>> print '%0.7e' % 1234.0001

    1.2340001e+03

    If you actually meant 7, then use %0.6e:

    >>> print '%0.6e' % 2.000001

    2.000001e+00
    >>> print '%0.6e' % 123456.789

    1.234568e+05
    >>> print '%0.6e' % 1234.0001

    1.234000e+03


    >
    > Is something like this possible (built-in) in python ?


    You can do more with gmpy.

    >
    > Really grateful for all the help and time you can spare.
    >
    > --
    > Ivan
    Mensanator, Sep 30, 2008
    #2
    1. Advertising

  3. Ivan Reborin

    Ivan Reborin Guest

    On Mon, 29 Sep 2008 16:08:28 -0700 (PDT), Mensanator
    <> wrote:

    >> 2. I've read the help on the next one but I just find it difficult
    >> understanding it.
    >> I have;
    >> a=2.000001
    >> b=123456.789
    >> c=1234.0001
    >>


    Hello Mensanator, thank you for answering in such a short time.

    < snip >

    >If you actually meant 7, then use %0.6e:


    Sorry about that; I have the habit of counting the point as a decimal
    place too.
    >
    >>>> print '%0.6e' % 2.000001

    >2.000001e+00
    >>>> print '%0.6e' % 123456.789

    >1.234568e+05
    >>>> print '%0.6e' % 1234.0001

    >1.234000e+03
    >


    I understood the above from help, but it's not what's been bugging me.
    Mea culpa, I've defined the question in a confusing way, I see that
    now. What I've meant to ask was, when I have 3 numbers, how would you
    print them with the same format which would apply to them 3 numbers.

    for example, I have
    print a,b,c

    now if I print them with
    print '%12.3f' %a,b,c
    the format will apply only to a, and not to b and c. I could of course
    write
    print '%12.3f %12.3f ... 3 times
    but that is just unpractical.

    Is there a way to just do something like this (not normal syntax, just
    my wishful thinking):
    print 3*'%12.3f' %a,b,c
    (meaning - use this format for the next 3 real numbers that come
    along)

    --
    Ivan
    Ivan Reborin, Sep 30, 2008
    #3
  4. Ivan Reborin

    Guest

    Ivan Reborin:
    > Is there a way to just do something like this (not normal syntax, just
    > my wishful thinking):
    > print 3*'%12.3f' %a,b,c
    > (meaning - use this format for the next 3 real numbers that come
    > along)


    The Python genie grants you that wish. You were almost right:

    >>> a = 2.000001
    >>> b = 123456.789
    >>> c = 1234.0001
    >>> print (3 * '%12.3f') % (a, b, c)

    2.000 123456.789 1234.000
    >>> print 3 * '%12.3f' % (a, b, c)

    2.000 123456.789 1234.000
    >>> print 3 * '%12.3f' % a, b, c

    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    TypeError: not enough arguments for format string

    (Note the spaces and parentheses. Python programmers thank you if put
    them improving readability a little).

    Bye,
    bearophile
    , Sep 30, 2008
    #4
  5. Ivan Reborin

    Ivan Reborin Guest

    On Mon, 29 Sep 2008 17:59:40 -0700 (PDT),
    wrote:

    Hello bearophile, thank you for replying.

    >The Python genie grants you that wish. You were almost right:
    >>>> print (3 * '%12.3f') % (a, b, c)

    > 2.000 123456.789 1234.000
    >>>> print 3 * '%12.3f' % (a, b, c)

    > 2.000 123456.789 1234.000

    Works beautifully :) Thank you!

    >>>> print 3 * '%12.3f' % a, b, c

    >Traceback (most recent call last):
    > File "<stdin>", line 1, in <module>
    >TypeError: not enough arguments for format string


    Just one more question - it's actually an extension to this one
    (forgive my curiosity, but I really need this info, and searching
    google always gives me the same stuff again and again) ...

    a = 2.000001
    b = 123456.789
    c = 1234.0001
    d = 98765.4321
    # same as above except for d

    print (3 * '%12.3f') % (a, b, c)
    #this works beautifully

    How to add d at the end but with a different format now, since I've
    "used" the "format part" ?

    Again, my weird wishful-thinking code:
    print (3*'%12.3f', '%5.3f') %(a,b,c),d


    >(Note the spaces and parentheses. Python programmers thank you if put
    >them improving readability a little).


    Yes, ok. I can agree with that - separating the format from the
    variable list part sounds reasonable.

    >
    >Bye,
    >bearophile


    --
    Ivan
    Ivan Reborin, Sep 30, 2008
    #5
  6. Ivan Reborin

    Chris Rebert Guest

    On Mon, Sep 29, 2008 at 6:56 PM, Ivan Reborin
    <> wrote:
    > On Mon, 29 Sep 2008 17:59:40 -0700 (PDT),
    > wrote:
    >
    > Hello bearophile, thank you for replying.
    >
    >>The Python genie grants you that wish. You were almost right:
    >>>>> print (3 * '%12.3f') % (a, b, c)

    >> 2.000 123456.789 1234.000
    >>>>> print 3 * '%12.3f' % (a, b, c)

    >> 2.000 123456.789 1234.000

    > Works beautifully :) Thank you!
    >
    >>>>> print 3 * '%12.3f' % a, b, c

    >>Traceback (most recent call last):
    >> File "<stdin>", line 1, in <module>
    >>TypeError: not enough arguments for format string

    >
    > Just one more question - it's actually an extension to this one
    > (forgive my curiosity, but I really need this info, and searching
    > google always gives me the same stuff again and again) ...
    >
    > a = 2.000001
    > b = 123456.789
    > c = 1234.0001
    > d = 98765.4321
    > # same as above except for d
    >
    > print (3 * '%12.3f') % (a, b, c)
    > #this works beautifully
    >
    > How to add d at the end but with a different format now, since I've
    > "used" the "format part" ?
    >
    > Again, my weird wishful-thinking code:
    > print (3*'%12.3f', '%5.3f') %(a,b,c),d


    Again, very close to the correct code:

    print (3*'%12.3f' + '%5.3f') %(a,b,c,d)

    Regards,
    Chris

    >
    >
    >>(Note the spaces and parentheses. Python programmers thank you if put
    >>them improving readability a little).

    >
    > Yes, ok. I can agree with that - separating the format from the
    > variable list part sounds reasonable.
    >
    >>
    >>Bye,
    >>bearophile

    >
    > --
    > Ivan
    > --
    > http://mail.python.org/mailman/listinfo/python-list
    >

    --
    Follow the path of the Iguana...
    http://rebertia.com
    Chris Rebert, Sep 30, 2008
    #6
  7. On Tue, 30 Sep 2008 03:56:03 +0200, Ivan Reborin wrote:

    > a = 2.000001
    > b = 123456.789
    > c = 1234.0001
    > d = 98765.4321
    > # same as above except for d
    >
    > print (3 * '%12.3f') % (a, b, c)
    > #this works beautifully
    >
    > How to add d at the end but with a different format now, since I've
    > "used" the "format part" ?
    >
    > Again, my weird wishful-thinking code: print (3*'%12.3f', '%5.3f')
    > %(a,b,c),d


    Maybe you should stop that wishful thinking and programming by accident
    and start actually thinking about what the code does, then it's easy to
    construct something working yourself.

    The ``%`` operator on strings expects a string on the left with format
    strings in it and a tuple with objects to replace the format strings
    with. So you want

    '%12.3f%12.3f%12.3f%5.3f' % (a, b, c, d)

    But without repeating the '%12.3f' literally. So you must construct that
    string dynamically by repeating the '%12.3f' and adding the '%5.3f':

    In [27]: 3 * '%12.3f'
    Out[27]: '%12.3f%12.3f%12.3f'

    In [28]: 3 * '%12.3f' + '%5.3f'
    Out[28]: '%12.3f%12.3f%12.3f%5.3f'

    Now you can use the ``%`` operator on that string:

    In [29]: (3 * '%12.3f' + '%5.3f') % (a, b, c, d)
    Out[29]: ' 2.000 123456.789 1234.00098765.432'

    (I guess there should be at least a space before the last format string.)

    This time you *have* to put parenthesis around the construction of the
    format string BTW because ``%`` has a higher priority than ``+``. So
    implicit parentheses look like this:

    3 * '%12.3f' + '%5.3f' % (a, b, c, d)
    <=> 3 * '%12.3f' + ('%5.3f' % (a, b, c, d))

    And there are of course not enough formatting place holders for four
    objects in '%5.3f'.

    It's also important to learn why your wrong codes fail. In your wishful
    thinking example you will get a `TypeError` saying "unsupported operand
    type(s) for %: 'tuple' and 'tuple'". That's because on the left side of
    the ``%`` operator you wrote a tuple:

    In [34]: (3 * '%12.3f', '%5.3f')
    Out[34]: ('%12.3f%12.3f%12.3f', '%5.3f')

    Ciao,
    Marc 'BlackJack' Rintsch
    Marc 'BlackJack' Rintsch, Sep 30, 2008
    #7
  8. On Tue, 30 Sep 2008 00:04:18 +0200, Ivan Reborin wrote:

    > 1. Multi dimensional arrays - how do you load them in python For
    > example, if I had:
    > -------
    > 1 2 3
    > 4 5 6
    > 7 8 9
    >
    > 10 11 12
    > 13 14 15
    > 16 17 18
    > -------
    > with "i" being the row number, "j" the column number, and "k" the ..
    > uhmm, well, the "group" number, how would you load this ?
    >
    > If fortran90 you would just do:
    >
    > do 10 k=1,2
    > do 20 i=1,3
    >
    > read(*,*)(a(i,j,k),j=1,3)
    >
    > 20 continue
    > 10 continue
    >
    > How would the python equivalent go ?


    Well, I don't know if this qualifies as equivalent:

    =====
    from __future__ import with_statement
    from functools import partial
    from itertools import islice
    from pprint import pprint


    def read_group(lines, count):
    return [map(int, s.split()) for s in islice(lines, count)]


    def main():
    result = list()

    with open('test.txt') as lines:
    #
    # Filter empty lines.
    #
    lines = (line for line in lines if line.strip())
    #
    # Read groups until end of file.
    #
    result = list(iter(partial(read_group, lines, 3), list()))

    pprint(result, width=30)


    if __name__ == '__main__':
    main()
    =====

    The output is:

    [[[1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]],
    [[10, 11, 12],
    [13, 14, 15],
    [16, 17, 18]]]

    `k` is the first index here, not the last and the code doesn't use fixed
    values for the ranges of `i`, `j`, and `k`, in fact it doesn't use index
    variables at all but simply reads what's in the file. Only the group
    length is hard coded in the source code.

    Ciao,
    Marc 'BlackJack' Rintsch
    Marc 'BlackJack' Rintsch, Sep 30, 2008
    #8
  9. Ivan Reborin

    Aidan Guest

    Ivan Reborin wrote:
    > Hello everyone,
    >
    > I was wondering if anyone here has a moment of time to help me with 2
    > things that have been bugging me.
    >
    > 1. Multi dimensional arrays - how do you load them in python
    > For example, if I had:
    > -------
    > 1 2 3
    > 4 5 6
    > 7 8 9
    >
    > 10 11 12
    > 13 14 15
    > 16 17 18
    > -------
    > with "i" being the row number, "j" the column number, and "k" the ..
    > uhmm, well, the "group" number, how would you load this ?
    >
    > If fortran90 you would just do:
    >
    > do 10 k=1,2
    > do 20 i=1,3
    >
    > read(*,*)(a(i,j,k),j=1,3)
    >
    > 20 continue
    > 10 continue
    >
    > How would the python equivalent go ?
    >
    > 2. I've read the help on the next one but I just find it difficult
    > understanding it.
    > I have;
    > a=2.000001
    > b=123456.789
    > c=1234.0001
    >
    > How do you print them with the same number of decimals ?
    > (eg. 2.000, 123456.789, 1234.000)
    > and how do you print them with the same number of significant
    > decimals?
    > (eg. 2.000001, 123456.7, 1234.000 - always 8 decimals) ?
    >
    >
    > Is something like this possible (built-in) in python ?
    >
    > Really grateful for all the help and time you can spare.
    >
    > --
    > Ivan



    I'm not sure if this is applicable to your multi-dimensional list
    problem... but it sounded a bit sudoku like (with row, columns and
    groups) so I thought I'd share a bit of code of developed in regards to
    solving sudoku puzzles...

    Given a list of 9 list elements, each with nine elements (lets call it
    sudoku_grid), the following list comprehensions produce lists of indexes
    into sudoku grid

    vgroups = [[(x,y) for y in xrange(9)] for x in xrange(9)]
    hgroups = [[(x,y) for x in xrange(9)] for y in xrange(9)]
    lgroups = [[(x,y) for x in xrange(a,a+3) for y in xrange(b,b+3)]
    for a in xrange(0,9,3) for b in xrange(0,9,3)]

    where sudoku_grid[y][x] yields the value at position (x,y), assuming the
    top left corner is indexed as (0,0)

    HTH
    Aidan, Sep 30, 2008
    #9
  10. Ivan Reborin

    Ivan Reborin Guest

    On 30 Sep 2008 07:07:52 GMT, Marc 'BlackJack' Rintsch <>
    wrote:

    Hello Marc, thanks for answering (on both subjects). I understand now
    the logic which lays behind what you were explaining in the other one.
    It cleared things quite a bit.

    >Well, I don't know if this qualifies as equivalent:
    >
    >=====
    >from __future__ import with_statement
    >from functools import partial
    >from itertools import islice
    >from pprint import pprint
    >
    >
    >def read_group(lines, count):
    > return [map(int, s.split()) for s in islice(lines, count)]
    >
    >def main():
    > result = list()
    > with open('test.txt') as lines:
    > lines = (line for line in lines if line.strip())
    > result = list(iter(partial(read_group, lines, 3), list()))
    > pprint(result, width=30)
    >if __name__ == '__main__':
    > main()
    >=====


    I'm afraid I must admit I find the code above totally uncomprehesible
    (I can't even see where the array here is mentioned - "result"?) and
    inpractical for any kind of engineering practice I had in mind.

    Does python, perchance, have some wrapper functions or something,
    which would allow one to load an array in a more natural "technical"
    way ? Like something mentioned above in my post (now deleted) ?

    Also, is there a way to change counter for arrays to go from 0 to 1 ?
    (first element being with the index 1) ?
    (probably not since that seems like a language implementation thing,
    but it doesn't hurt to ask)

    --
    Ivan
    Ivan Reborin, Sep 30, 2008
    #10
  11. On Tue, 30 Sep 2008 15:42:58 +0200, Ivan Reborin wrote:

    > On 30 Sep 2008 07:07:52 GMT, Marc 'BlackJack' Rintsch <>
    > wrote:
    >>=====
    >>from __future__ import with_statement from functools import partial
    >>from itertools import islice
    >>from pprint import pprint
    >>
    >>
    >>def read_group(lines, count):
    >> return [map(int, s.split()) for s in islice(lines, count)]
    >>
    >>def main():
    >> with open('test.txt') as lines:
    >> lines = (line for line in lines if line.strip())
    >> result = list(iter(partial(read_group, lines, 3), list()))
    >> pprint(result, width=30)
    >>
    >>if __name__ == '__main__':
    >> main()
    >>=====

    >
    > I'm afraid I must admit I find the code above totally uncomprehesible (I
    > can't even see where the array here is mentioned - "result"?) and
    > inpractical for any kind of engineering practice I had in mind.


    Learn Python then to understand that code. ;-)

    There is no array. The data type is called "list" in Python, so `result`
    is a nested list. And in Python it quite unusual to build lists by
    creating them with the final size filled with place holder objects and
    then fill the real values in. Instead lists are typically created by
    appending values to existing lists, using list comprehension or the
    `list()` function with some iterable object.

    Typical Python code tries to minimize the use of index variables. Python
    is not Fortran (or C, or Pascal, …).

    > Does python, perchance, have some wrapper functions or something, which
    > would allow one to load an array in a more natural "technical" way ?
    > Like something mentioned above in my post (now deleted) ?
    >
    > Also, is there a way to change counter for arrays to go from 0 to 1 ?


    You can write your own sequence type but that would be odd because the
    rest of the language expects zero as the first index, so you will be
    constantly fighting the language by adding or subtracting 1 all the time
    at the "border" between your custom sequence type and the the rest of
    Python.

    Ciao,
    Marc 'BlackJack' Rintsch
    Marc 'BlackJack' Rintsch, Sep 30, 2008
    #11
  12. On Tue, 30 Sep 2008 00:04:18 +0200, Ivan Rebori wrote:
    >
    > 1. Multi dimensional arrays - how do you load them in python
    > For example, if I had:
    > -------
    > 1 2 3
    > 4 5 6
    > 7 8 9
    >
    > 10 11 12
    > 13 14 15
    > 16 17 18
    > -------
    > with "i" being the row number, "j" the column number, and "k" the ..
    > uhmm, well, the "group" number, how would you load this ?
    >
    > If fortran90 you would just do:
    >
    > do 10 k=1,2
    > do 20 i=1,3
    >
    > read(*,*)(a(i,j,k),j=1,3)
    >
    > 20 continue
    > 10 continue
    >
    > How would the python equivalent go ?


    Since you're coming from the FORTRAN world (thank you for
    that stroll down Memory Lane), you might be doing scientific
    computations, and so might be interested in the SciPy
    package (Google scipy), which gives you arrays and matrices.
    Don't expect to be able to use it without learning some Python,
    though.

    --
    To email me, substitute nowhere->spamcop, invalid->net.
    Peter Pearson, Sep 30, 2008
    #12
  13. On Tue, 30 Sep 2008 10:57:19 -0500, Grant Edwards wrote:

    > On 2008-09-30, Peter Pearson <> wrote:
    >> On Tue, 30 Sep 2008 00:04:18 +0200, Ivan Rebori wrote:
    >>>
    >>> 1. Multi dimensional arrays - how do you load them in python For
    >>> example, if I had:
    >>> -------
    >>> 1 2 3
    >>> 4 5 6
    >>> 7 8 9
    >>>
    >>> 10 11 12
    >>> 13 14 15
    >>> 16 17 18
    >>> -------
    >>> with "i" being the row number, "j" the column number, and "k" the ..
    >>> uhmm, well, the "group" number, how would you load this ?
    >>>
    >>> If fortran90 you would just do:
    >>>
    >>> do 10 k=1,2
    >>> do 20 i=1,3
    >>>
    >>> read(*,*)(a(i,j,k),j=1,3)
    >>>
    >>> 20 continue
    >>> 10 continue
    >>>
    >>> How would the python equivalent go ?

    >
    > You would drag yourself out of the 1960s, install numpy, and then do
    > something like this:
    >
    > a = read_array(open("filename.dat","r"))


    In [64]: a = numpy.fromfile('test.txt', dtype=int, sep=' ')

    In [65]: a
    Out[65]:
    array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
    18])

    In [66]: a.reshape(2, 3, 3)
    Out[66]:
    array([[[ 1, 2, 3],
    [ 4, 5, 6],
    [ 7, 8, 9]],

    [[10, 11, 12],
    [13, 14, 15],
    [16, 17, 18]]])

    Ciao,
    Marc 'BlackJack' Rintsch
    Marc 'BlackJack' Rintsch, Sep 30, 2008
    #13
  14. Ivan Reborin

    Ivan Reborin Guest

    On 30 Sep 2008 15:31:59 GMT, Peter Pearson <>
    wrote:

    >
    >Since you're coming from the FORTRAN world (thank you for
    >that stroll down Memory Lane), you might be doing scientific
    >computations, and so might be interested in the SciPy
    >package (Google scipy), which gives you arrays and matrices.
    >Don't expect to be able to use it without learning some Python,
    >though.


    Actually, no (regarding memory lane :). I'm helping a friend to
    translate some of my old routines to python so he can use them in his
    programs.
    I'm still using fortran84, and mean to continue doing so as long as
    something better doesn't come along.

    But as I said, got a job that't got to be done, so I'm trying to
    figure out how to do array operations as easily as possible in python,
    which are necessary for all my calculations.

    Best regards
    Ivan
    Ivan Reborin, Sep 30, 2008
    #14
  15. On Tue, 30 Sep 2008 10:57:19 -0500, Grant Edwards wrote:

    >>> How would the python equivalent go ?

    >
    > You would drag yourself out of the 1960s, install numpy, and then do
    > something like this:


    I think that was thoughtlessly rude to somebody who is asking a perfectly
    reasonable question.


    --
    Steven
    Steven D'Aprano, Oct 1, 2008
    #15
  16. On Tue, 30 Sep 2008 14:34:31 +0000, Marc 'BlackJack' Rintsch wrote:

    > On Tue, 30 Sep 2008 15:42:58 +0200, Ivan Reborin wrote:
    >
    >> On 30 Sep 2008 07:07:52 GMT, Marc 'BlackJack' Rintsch <>
    >> wrote:
    >>>=====
    >>>from __future__ import with_statement from functools import partial
    >>>from itertools import islice
    >>>from pprint import pprint
    >>>
    >>>
    >>>def read_group(lines, count):
    >>> return [map(int, s.split()) for s in islice(lines, count)]
    >>>
    >>>def main():
    >>> with open('test.txt') as lines:
    >>> lines = (line for line in lines if line.strip())
    >>> result = list(iter(partial(read_group, lines, 3), list()))
    >>> pprint(result, width=30)
    >>>
    >>>if __name__ == '__main__':
    >>> main()
    >>>=====

    >>
    >> I'm afraid I must admit I find the code above totally uncomprehesible
    >> (I can't even see where the array here is mentioned - "result"?) and
    >> inpractical for any kind of engineering practice I had in mind.

    >
    > Learn Python then to understand that code. ;-)
    >
    > There is no array. The data type is called "list" in Python, so
    > `result` is a nested list. And in Python it quite unusual to build
    > lists by creating them with the final size filled with place holder
    > objects and then fill the real values in. Instead lists are typically
    > created by appending values to existing lists, using list comprehension
    > or the `list()` function with some iterable object.


    I would weaken that claim a tad... I'd say it is "usual" to write
    something like this:

    alist = []
    for x in some_values:
    alist.append(something_from_x)


    but it is not uncommon (at least not in my code) to write something like
    this equivalent code instead:

    alist = [None]*len(some_values)
    for i, x in enumerate(some_values):
    alist = something_from_x


    Most often the first way is most natural, but the second way is sometimes
    more natural. It will also be more familiar to somebody coming from
    Fortran, and it is a micro-optimization for large lists because it
    doesn't need to resize the list as it grows.

    I stress the *micro*-optimization, because Python lists are highly
    optimized to resize as rarely as possible and as quickly as possible, so
    you're not saving much time.

    And Marc, I think you're being a little unfair to the OP, who is clearly
    unfamiliar with Python. I've been using Python for perhaps ten years, and
    I still find your code above dense and hard to comprehend. It uses a
    number of "advanced Python concepts" that a newbie is going to have
    trouble with:

    - the with statement acts by magic; if you don't know what it does, it's
    an opaque black box.

    - you re-use the same name for different uses, which can cause confusion.

    - generator expressions.

    - functional programming using partial.

    - you call a function that uses a list comprehension with both map and
    iterator slicing inside it.


    No wonder the OP had trouble with it. *I* have trouble with it, and would
    need to sit down at the interactive interpreter and play around with it
    for a while to be sure what it actually does. If it was your intention to
    make Python look as obtuse and mysterious as possible, you almost
    succeeded. The one things you missed was to replace the read_group
    function with a lambda in the partial.



    --
    Steven
    Steven D'Aprano, Oct 1, 2008
    #16
  17. En Mon, 29 Sep 2008 19:04:18 -0300, Ivan Reborin
    <> escribió:

    > 1. Multi dimensional arrays - how do you load them in python
    > For example, if I had:
    > -------
    > 1 2 3
    > 4 5 6
    > 7 8 9
    >
    > 10 11 12
    > 13 14 15
    > 16 17 18
    > -------
    > with "i" being the row number, "j" the column number, and "k" the ..
    > uhmm, well, the "group" number, how would you load this ?


    I agree that using NumPy is the way to go if you're going to do lots of
    array calculations. But a plain Python code would look like this (more
    comprehensible than other posted versions, I hope):

    --- begin code ---
    def read_group(fin, rows_per_group):
    rows = []
    for i in range(rows_per_group):
    line = fin.readline()
    row = [float(x) for x in line.split()]
    rows.append(row)
    fin.readline() # skip blank line
    return rows

    # simulate a file using a string instead
    # actual code would use: fin = open(filename)

    from StringIO import StringIO
    fin = StringIO("""1 2 3
    4 5 6
    7 8 9

    10 11 12
    13 14 15
    16 17 18
    """)

    # read 2 groups of 3 lines each
    matrix = [read_group(fin, 3) for k in range(2)]
    print matrix
    --- end code ---

    A more compact version of read_group (collapsing all rows.append onto the
    outer list comprehension):

    --- begin code ---
    def read_group(fin, rows_per_group):
    rows = [[float(x) for x in fin.readline().split()]
    for i in range(rows_per_group)]
    fin.readline() # skip blank line
    return rows
    --- end code ---

    --
    Gabriel Genellina
    Gabriel Genellina, Oct 1, 2008
    #17
  18. Ivan Reborin

    Paul Probert Guest

    Grant Edwards wrote:
    > On 2008-09-30, Peter Pearson <> wrote:
    >> On Tue, 30 Sep 2008 00:04:18 +0200, Ivan Rebori wrote:
    >>> 1. Multi dimensional arrays - how do you load them in python
    >>> For example, if I had:
    >>> -------
    >>> 1 2 3
    >>> 4 5 6
    >>> 7 8 9
    >>>
    >>> 10 11 12
    >>> 13 14 15
    >>> 16 17 18
    >>> -------
    >>> with "i" being the row number, "j" the column number, and "k" the ..
    >>> uhmm, well, the "group" number, how would you load this ?
    >>>
    >>> If fortran90 you would just do:
    >>>
    >>> do 10 k=1,2
    >>> do 20 i=1,3
    >>>
    >>> read(*,*)(a(i,j,k),j=1,3)
    >>>
    >>> 20 continue
    >>> 10 continue
    >>>
    >>> How would the python equivalent go ?

    >
    > You would drag yourself out of the 1960s, install numpy, and
    > then do something like this:
    >
    > a = read_array(open("filename.dat","r"))
    >
    >> Since you're coming from the FORTRAN world (thank you for that
    >> stroll down Memory Lane), you might be doing scientific
    >> computations, and so might be interested in the SciPy package
    >> (Google scipy), which gives you arrays and matrices. Don't
    >> expect to be able to use it without learning some Python,
    >> though.

    >
    > If not full-up scipy (which provides all sorts of scientific
    > and numerical-analysis stuff), then at least numpy (which
    > provides the basic array/matrix operations:
    >
    > http://numpy.scipy.org/
    >
    > Though the software is free, the documentation isn't. You've
    > got to buy the book if you want something to read. IMO, it's
    > definitely worth it, and a good way to support the project even
    > if you don't really need something to keep your bookends apart.

    clip ...
    The book is free now, as of Aug 21, 08.
    http://www.tramy.us/guidetoscipy.html

    Paul Probert
    Paul Probert, Oct 1, 2008
    #18
  19. On Tue, 30 Sep 2008 23:40:22 +0000, Steven D'Aprano wrote:

    > On Tue, 30 Sep 2008 14:34:31 +0000, Marc 'BlackJack' Rintsch wrote:
    >
    >> There is no array. The data type is called "list" in Python, so
    >> `result` is a nested list. And in Python it quite unusual to build
    >> lists by creating them with the final size filled with place holder
    >> objects and then fill the real values in. Instead lists are typically
    >> created by appending values to existing lists, using list comprehension
    >> or the `list()` function with some iterable object.

    >
    > I would weaken that claim a tad... I'd say it is "usual" to write
    > something like this:
    >
    > alist = []
    > for x in some_values:
    > alist.append(something_from_x)
    >
    >
    > but it is not uncommon (at least not in my code) to write something like
    > this equivalent code instead:
    >
    > alist = [None]*len(some_values)
    > for i, x in enumerate(some_values):
    > alist = something_from_x


    I have never done this, except in the beginning I used Python, and --
    maybe more importantly -- I've never seen this in others code. I really
    looks like a construct from someone who is still programming in some
    other language(s).

    > Most often the first way is most natural, but the second way is
    > sometimes more natural.


    When will it be more natural to introduce an unnecessary index?

    > And Marc, I think you're being a little unfair to the OP, who is clearly
    > unfamiliar with Python. I've been using Python for perhaps ten years,
    > and I still find your code above dense and hard to comprehend. It uses a
    > number of "advanced Python concepts" that a newbie is going to have
    > trouble with:
    >
    > - the with statement acts by magic; if you don't know what it does, it's
    > an opaque black box.


    Everything acts by magic unless you know what it does. The Fortran

    read(*,*)(a(i,j,k),j=1,3)

    in the OP's first post looks like magic too. I admit that my code shows
    off advanced Python features but I don't think ``with`` is one of them.
    It makes it easier to write robust code and maybe even understandable
    without documentation by just reading it as "English text".

    > - you re-use the same name for different uses, which can cause
    > confusion.


    Do you mean `lines`? Then I disagree because the (duck) type is always
    "iterable over lines". I just changed the content by filtering.

    > - generator expressions.
    >
    > - functional programming using partial.
    >
    > - you call a function that uses a list comprehension with both map and
    > iterator slicing inside it.
    >
    >
    > No wonder the OP had trouble with it. *I* have trouble with it, and
    > would need to sit down at the interactive interpreter and play around
    > with it for a while to be sure what it actually does. If it was your
    > intention to make Python look as obtuse and mysterious as possible, you
    > almost succeeded. The one things you missed was to replace the
    > read_group function with a lambda in the partial.


    Well that would make the code harder to understand. ;-)

    Serious, I think it should be easy to understand the code for someone who
    knows Python. Yes a newbie will have trouble to understand this, but
    Python is not Fortran and IMHO I haven't used something really exotic or
    strange nor did I wrote convoluted and hard to understand things like
    deeply nested list comprehensions.

    Ciao,
    Marc 'BlackJack' Rintsch
    Marc 'BlackJack' Rintsch, Oct 1, 2008
    #19
  20. On Tue, 30 Sep 2008 19:44:40 -0500, Grant Edwards wrote:

    > On 2008-09-30, Steven D'Aprano <>
    > wrote:
    >> On Tue, 30 Sep 2008 10:57:19 -0500, Grant Edwards wrote:
    >>
    >>>>> How would the python equivalent go ?
    >>>
    >>> You would drag yourself out of the 1960s, install numpy, and then do
    >>> something like this:

    >>
    >> I think that was thoughtlessly rude to somebody who is asking a
    >> perfectly reasonable question.

    >
    > Sheesh. I guess I should have added a smiley face.
    >
    > So much for trying to be helpful.



    Oh the rest of your post was helpful. I think you were trying to be
    funny, but I think you failed.




    --
    Steven
    Steven D'Aprano, Oct 1, 2008
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. DeadInPlastic
    Replies:
    1
    Views:
    782
    Karl Heinz Buchegger
    Jun 26, 2003
  2. mark
    Replies:
    1
    Views:
    713
    Victor Bazarov
    Jun 19, 2004
  3. =?ISO-8859-1?Q?Gregory_Pi=F1ero?=

    How do I put % in a format sting?

    =?ISO-8859-1?Q?Gregory_Pi=F1ero?=, Oct 5, 2006, in forum: Python
    Replies:
    5
    Views:
    256
    John Salerno
    Oct 6, 2006
  4. David Gerber

    need to remove a portion of a sting

    David Gerber, Dec 23, 2011, in forum: Ruby
    Replies:
    1
    Views:
    472
    gerberdata
    Dec 23, 2011
  5. seven.reeds
    Replies:
    1
    Views:
    190
    seven.reeds
    Aug 9, 2009
Loading...

Share This Page