I'm currently using the following:
>>> sys.stdout.write('Number = %s\n' % '{:,.0f}'.format(x))
Number = 12,345
'x' is unsigned integer so it's like using a sledgehammer to crack a nut!
I'd like to have something like:
sys.stdout.write('Number = %,u\n' % x)
Is that possible? How can I do it if not already available?
--
Ned Deily,
n...@acm.org
--
http://mail.python.org/mailman/listinfo/python-list
Thank you, but let me rephrase it. I'm already using str.format() but I'd like to use '%' (BINARY_MODULO) operator instead.
I've looked into the source code of CPython 2.7.5 and I've found no evidence of the thousands separator been implemented on formatint() in "Objects/unicodeobject.c".
I also didn't find the _PyString_FormatLong() used in formatlong(). Where is _PyString_FormatLong() located?
So, the question is: Where would I change the CPython 2.7.5 source code to enable '%' (BINARY_MODULO) to format using the thousands separator like str.format() does, such as:
>>>sys.stderr.write('%,d\n' % 1234567)
1,234,567
I did:
>>> def fmt(s):
... return '%s' % s
...
>>> import dis
>>> dis.dis(fmt)
2 0 LOAD_CONST 1 ('%s')
3 LOAD_FAST 0 (s)
6 BINARY_MODULO
7 RETURN_VALUE
>>>
Then I've looked for 'BINARY_MODULO' in "Python/ceval.c" and found:
case BINARY_MODULO:
w = POP();
v = TOP();
if (PyString_CheckExact(v))
x = PyString_Format(v, w);
else
x = PyNumber_Remainder(v, w);
Then I've looked for 'PyString_Format' and found it in "Objects/stringobject.c"
Analysing the code of "stringobject.c" I've found formatint() and formatlong().
I'm not using str.format() because it's slower than '%' and because I love '%'. str.format() looks like Java shit to me!
>> So, the question is: Where would I change the CPython 2.7.5 source code to enable '%' (BINARY_MODULO) to format using the thousands separator like str.format() does, such as:
>>
>>>>>sys.stderr.write('%,d\n' % 1234567)
>> 1,234,567
>
> This will make your code unportable and useless, depending on one
> patch you made. Please don’t do that. Instead,
I'm just learning how to improve things! ;)
>>>>> sys.stdout.write('Number = %s\n' % '{:,.0f}'.format(x))
>> Number = 12,345
>>
>> 'x' is unsigned integer so it's like using a sledgehammer to crack a nut!
>
> In Python? Tough luck, every int is signed. And it isn’t just a
> sledgehammer, it’s something worse. Just do that:
>
>>>> sys.stdout.write('Number = {:,.0f}\n'.format(x))
>
> Much more peaceful.
Indeed! I just cut and pasted my code to create an example for the message. The actual format operation isn't done at the sys.stdout.write().
> You can also do a print, like everyone sane would. Where did you
> learn Python from? “Python Worst Practice for Dummies”?
lol I'm learning from my big mistakes up to now and a ton of online tutorials, besides "Dive into Python" (2004)[1], "Python Programming" (2012)[2] and "Programming Python, 3rd Ed" (2006) [print]
print isn't thread safe. That's why I've chosen sys.stdout.write() -- it's faster and thread safe by default.
I don't need any fancy formating, just need to send the string to screen.
[1] http://www.diveintopython.net/
[1] http://en.wikibooks.org/wiki/Python_Programming
I mean _PyString_FormatLong()
I used to think str.__mod__() was going to be deprecated until Steven told me it was a myth! Think I got that idea from the own Python docs, but it's gone by now. Nevermind...
The fact is I have no need for str.format(). It's slow and awkward. str.format() looks like COBOL/Java idiom to me. I love Python! '%' is much more cool!!!
> Please stop perpetuating this myth, see
> http://mail.python.org/pipermail/python-dev/2012-February/116789.html
> and http://bugs.python.org/issue14123
>
> --
> If you're using GoogleCrap™ please read this
> http://wiki.python.org/moin/GoogleGroupsPython.
>
> Mark Lawrence
>
> --
> http://mail.python.org/mailman/listinfo/python-list
I vote for keeping str.__mod__()!
Anyway, is it possible to overload str.__mod__() without deriving a class? I mean to have something like:
old_mod = str.__mod__
def new_mod(x):
global old_mod
try:
old_mod(x)
except ValueError, ex:
#catch ValueError: unsupported format character ',' (0x2c) at index 1
#process new '%,d' format here
return '{:,}'.format(x) #just to illustrate the behaviour. it would have it's own faster code
str.__mod__ = new_mod #this raises TypeError: can't set attributes of built-in/extension type 'str'
sys.stdout.write('num=%,d\n' % 1234567)
> --
> CPython 3.3.2 | Windows NT 6.2.9200 / FreeBSD 9.1
So, the only alternative to have "'%,d' % x" rendering the thousands separator output would a C source code modification?
> --
> Steven
> --
> http://mail.python.org/mailman/listinfo/python-list
Not fighting the language. In fact it's not even a language issue.
All I need is a standard library[1] improvement: "%,d"! That's all!
Just to put in perspective the performance difference of str.__mod__() and str.format():
C:\Python27>python -m timeit -cv -n10000000 "'%d'%12345"
raw times: 0.386 0.38 0.373
10000000 loops, best of 3: 0.0373 usec per loop
C:\Python27>python -m timeit -cv -n10000000 "'{:d}'.format(12345)"
raw times: 7.91 7.89 7.98
10000000 loops, best of 3: 0.789 usec per loop
C:\Python27>python -m timeit -cv -n10000000 "'{:,d}'.format(12345)"
raw times: 8.7 8.67 8.78
10000000 loops, best of 3: 0.867 usec per loop
That shows str.format() is 20 times slower than str.__mod__() for a simple decimal integer literal formatting.
And it's additionally 10% slower if the thousands separator format specifier (',') is used.
[1] I think that translates to Python source code in 'Objects/stringobject.c' and maybe 'Objects/unicodeobject.c'
No problem. I have just discovered i was measuring the wrong thing.
My test case is been optimized at compile time by CPython that treats "'%d' % 12345" as a constant.
My use case is different because I almost have no literals been used with % operator.
So my gain isn't that great. In fact it's faster with str.format() than %, and it's even faster if I use the default format specifier.
C:\Python27>python -m timeit -cv -n10000000 -s"v=12345" "'%d'%v"
raw times: 10.5 10.7 10.7
10000000 loops, best of 3: 1.05 usec per loop
C:\Python27>python -m timeit -cv -n10000000 -s"v=12345" "'{:d}'.format(v)"
raw times: 8.11 8.09 8.02
10000000 loops, best of 3: 0.802 usec per loop
C:\Users\Josue\Documents\Python>python -m timeit -cv -n10000000 -s"v=12345" "'{}'.format(v)"
raw times: 5.3 5.5 5.62
10000000 loops, best of 3: 0.53 usec per loop
Using variables (100% of cases) makes str.format() 50% faster than %.
I still don't understand why % benefits from literals optimization ("'%d'%12345") while '{:d}'.format(12345) doesn't.
What "totally different" you talking about? Please give me an example.
Maybe I'll look into that later, but I couldn't even find how the hell they made _Py_InsertThousandsGrouping() been called.
That's what I got when analysing % formating:
Thousands separator format specifier for str.__mod__()
======================================================
@Objects/stringobject.c: implements formatint() for '%' processing
-Looking for code used in str.format()
@Objects/stringlib/formatter.h: implements str.format()
-It uses STRINGLIB_GROUPING() to do the job.
@Objects/stringlib/stringdefs.h: #define STRINGLIB_GROUPING _PyString_InsertThousandsGrouping
@Objects/stringlib/unicodedefs.h: #define STRINGLIB_GROUPING _PyUnicode_InsertThousandsGrouping
@Objects/stringobject.c: #define _Py_InsertThousandsGrouping _PyString_InsertThousandsGrouping
@Objects/stringobject.h: declares _PyString_InsertThousandsGrouping()
@???: ??? _PyString_InsertThousandsGrouping ??? _Py_InsertThousandsGrouping
@Objects/stringlib/localeutil.h: implements _Py_InsertThousandsGrouping()
Let me explain what that means. I found no relating declarations/definitions that turn _PyString_InsertThousandsGrouping into _Py_InsertThousandsGrouping.
So, I don't even know how that source code compiles without error.
:/ really strange...
Not to mention the lots of code inside header definition files! Weird!!!!
So % doesn't handle tuples! Why's that? Is it intentional (by design)?
Thanks so much guys! Now I understand why some people hate %-formatting!
I don't think that's a problem because there's no format specifier for tuples in the %-formatting definition[1].
So it's up to the user to make the necessary conversion.
I still love the %-formatting style!
Can str.format() do the following?
f = '%d %d %d'
v = '1,2,3'
print f % eval(v)
If yes, how?
[1] http://docs.python.org/2/library/stdtypes.html#string-formatting
Can str.format() do the following?
f = '%d %d %d'
v = '1,2,3'
print f % eval(v)
________________________________
> Date: Thu, 23 May 2013 21:17:54 -0400
> Subject: Re: PEP 378: Format Specifier for Thousands Separator
> From: malac...@gmail.com
> To: carlosne...@outlook.com
> CC: pytho...@python.org
>
> On Thu, May 23, 2013 at 6:20 PM, Carlos Nepomuceno
> <carlosne...@outlook.com<mailto:carlosne...@outlook.com>>
I'm sorry but I don't understand your question.
Do you mean returning the output of another process to the caller? Like:
import subprocess
output = subprocess.check_output(['ping', 'google.com'])
----------------------------------------
> Date: Fri, 24 May 2013 19:28:29 +0200
> From: andip...@gmail.com
> To: pytho...@python.org
> Subject: Re: PEP 378: Format Specifier for Thousands Separator
>
> On 24.05.2013 17:25, Carlos Nepomuceno wrote:
>> ----------------------------------------
>>> Date: Thu, 23 May 2013 19:29:14 -0700
>>> Subject: Re: PEP 378: Format Specifier for Thousands Separator
>>> From: dihedr...@gmail.com
>>> [some typical dihedral stuff]
>>
>> I'm sorry but I don't understand your question.
>
> Don't worry. I guess most people on this list don't understand it either.
>
> It looks like dihedral is a bot although nobody knows for sure. Search
> for some other posts from him/her/it in the archive and form your own
> opinion.
>
> IMHO you can simply ignore him/her/it.
>
> Bye, Andreas
>