Velocity Reviews > Python arrays and sting formatting options

# Python arrays and sting formatting options

Ivan Reborin
Guest
Posts: n/a

 09-29-2008
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
-------
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

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

Mensanator
Guest
Posts: n/a

 09-29-2008
On Sep 29, 5:04*pm, Ivan Reborin <(E-Mail Removed)>
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
>
>
> 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

Ivan Reborin
Guest
Posts: n/a

 09-30-2008
On Mon, 29 Sep 2008 16:08:28 -0700 (PDT), Mensanator
<(E-Mail Removed)> 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

bearophileHUGS@lycos.com
Guest
Posts: n/a

 09-30-2008
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

Bye,
bearophile

Ivan Reborin
Guest
Posts: n/a

 09-30-2008
On Mon, 29 Sep 2008 17:59:40 -0700 (PDT), http://www.velocityreviews.com/forums/(E-Mail Removed)
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

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

>
>Bye,
>bearophile

--
Ivan

Chris Rebert
Guest
Posts: n/a

 09-30-2008
On Mon, Sep 29, 2008 at 6:56 PM, Ivan Reborin
<(E-Mail Removed)> wrote:
> On Mon, 29 Sep 2008 17:59:40 -0700 (PDT), (E-Mail Removed)
> 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

>
> 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

Marc 'BlackJack' Rintsch
Guest
Posts: n/a

 09-30-2008
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
Guest
Posts: n/a

 09-30-2008
On Tue, 30 Sep 2008 00:04:18 +0200, Ivan Reborin wrote:

> 1. Multi dimensional arrays - how do you load them in python For
> -------
> 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
>
>
> 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

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

Aidan
Guest
Posts: n/a

 09-30-2008
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
>
>
> 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

Ivan Reborin
Guest
Posts: n/a

 09-30-2008
On 30 Sep 2008 07:07:52 GMT, Marc 'BlackJack' Rintsch <(E-Mail Removed)>
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
>
>
> 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