Reputation: 19
So I am fairly new to Python as I am sure will become apparent. Anyways, is there a limit to the number of arguments I can pass when using .format? I have a list of 8000 numbers that need to replace existing numbers in a long input in various places in the input. At the moment, I am planning on doing this:
text = """ very long input with many {0}..{1}..{8000} in various places """
file = open('new_input', 'w')
file.write(text.format(x,x1,x2,....x8000))
Any advice would be much appreciated!
Upvotes: 1
Views: 471
Reputation: 155506
As wim notes, you could do it with argument unpacking, but if you actually passed them positionally as individual named arguments, it wouldn't work; there is a limit of 255 explicitly provided individual arguments.
Demonstration:
>>> globals().update(('x{}'.format(i), i) for i in range(8000))
>>> codestr = '("{{}}"*8000).format({})'.format(', '.join('x{}'.format(i) for i in range(8000)))
>>> eval(codestr)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1
SyntaxError: more than 255 arguments
The limit is due to how the CALL_FUNCTION
opcode is defined; it's encoded as a single byte indicating the opcode, then one byte for the number of positional arguments, and one for the number of keyword arguments. While in theory it could handle up to 510 total arguments, they actually impose a combined limit of 255 arguments, presumably for consistency. So you can't actually call a function with more than 255 total arguments without involving *
or **
unpacking.
This is all technically an implementation detail BTW; there is no language requirement that it work this way, so it could change in a future release of CPython (the reference interpreter) and behave differently in any other interpreter (most of which don't produce or use CPython bytecode anyway) right now.
Upvotes: 5
Reputation: 363083
I'm not aware of any hard limit and 8000 is not that big anyway, I think it should not be any problem.
Example with positional templating:
>>> text = "{} "*8000
>>> text = text.format(*range(8000))
>>> '{' in text
False
>>> text[:50]
'0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 '
>>> text[-50:]
'7990 7991 7992 7993 7994 7995 7996 7997 7998 7999 '
Example with name templating:
>>> s = ' '.join(['{{x{}}}'.format(i) for i in range(8000)])
>>> d = {'x{}'.format(i):i for i in range(8000)}
>>> s[:25] + '...' + s[-24:]
'{x0} {x1} {x2} {x3} {x4} ... {x7997} {x7998} {x7999}'
>>> s = s.format(**d)
>>> s[:25] + '...' + s[-24:]
'0 1 2 3 4 5 6 7 8 9 10 11...7995 7996 7997 7998 7999'
Upvotes: 4