Have a "j" format option for lists

This way, I could do:
In this case the join can be made in the format yes, but this proposal would be very useful when the info to format comes inside a structure together with other stuff, like...
What do you think? -- . Facundo Blog: http://www.taniquetil.com.ar/plog/ PyAr: http://www.python.org/ar/ Twitter: @facundobatista

On Wed, May 09, 2018 at 09:39:08AM -0300, Facundo Batista wrote:
Looks interesting, but I think we need to know the semantics in more detail. For example: - if the items of the list aren't already strings, how are they converted? - do you truly mean lists *only*, or is any iterable acceptible? Here's a tiny proof-of-concept for the feature: import string class Template(string.Formatter): def format_field(self, value, spec): if spec.endswith('j'): value = ', '.join(map(str, value)) spec = spec[:-1] + 's' return super(Template, self).format_field(value, spec) Template().format('{:j} => {:d}', ['alpha', 'beta', 42, 'delta'], 99) # returns 'alpha, beta, 42, delta => 99' -- Steve

On Wed, May 9, 2018 at 11:06 PM, Steven D'Aprano <steve@pearwood.info> wrote:
I'd expect that they'd be converted using format(), which by default would just call str(). How you'd go about specifying a format string, though, I'm not sure.
- do you truly mean lists *only*, or is any iterable acceptible?
From the sound of it, this would be a change made to format(), or rather the underlying C level function, PyObject_Format(). If done
With the letter being "j" and the semantics being lifted from str.join(), I would guess the latter. there, it would also automatically apply to f-strings and anything else that calls format(). Perhaps the right way is not a colon marker, but an enhancement to the ! notation? We currently have !s and !r to do str() and repr(), and this could be !j followed by a join string. Combining this with a colon would allow the individual elements to be formatted with the given string, and then joined. For instance: x = [1,2,3] msg = '#{x:3d!j, }#'.format(x=x) # or equivalently msg = f'#{x:3d!j, }#' assert msg == '# 1, 2, 3#' +0.5 on this. I don't currently yearn for it, but I'd probably use it if it were available. ChrisA

On 5/9/18 9:28 AM, Chris Angelico wrote:
Since '{:spec}'.format(obj) basically becomes obj.__format__('spec'), this would have to be implemented on a concrete type (in the above example, list).
I would object to changing the format machinery. Any format spec should be interpreted by some object's __format__ method. Eric

On 9 May 2018 at 14:49, Eric V. Smith <eric@trueblade.com> wrote:
[...]
I would object to changing the format machinery. Any format spec should be interpreted by some object's __format__ method.
Agreed. In theory this is a nice idea, but the way formatting is implemented (and the fact that join is a method on strings taking an arbitrary iterable as an argument) means that it's a bad fit for the format mini-language. I don't think the improved convenience is sufficient to warrant the change that would be required in practice. (But if someone found a way to make it work *without* changes to the underlying format machinery, that would be a different matter...) Paul

On 5/9/18 10:01 AM, Paul Moore wrote:
Well, since you asked, let's combine this with dataclasses, because we can! from dataclasses import dataclass from typing import List @dataclass class Join: o: List[str] # or similar def __format__(self, spec): return spec.join(self.o) l = ['a', 'b'] print('{:, }'.format(Join(l))) print(f'{Join(l):-}') Gives: a, b a-b Eric

On 9 May 2018 at 15:29, Eric V. Smith <eric@trueblade.com> wrote:
:-) Sorry, I should have been clearer. Given that print('{}'.format(', '.join(l))) isn't that difficult, at least for me the attraction of the proposal was the possibility of not having to wrap the argument (whether in a function call, or in a custom class). But the print(f'{Join(l):-}') approach is certainly cleaner looking than print(f'{", ".join(l)}'). Paul

On 05/09/2018 02:39 PM, Facundo Batista wrote:
For reference (first message of a rather long previous thread): https://mail.python.org/pipermail/python-ideas/2015-September/035787.html

On 09/05/18 13:39, Facundo Batista wrote:
-1 until you give me an actual spec rather than a curious example. Sorry if that sounds a bit rude, but I spend most of my time trying to find polite ways to inform people that I'm perfectly capable of implementing the fluffy collection of vague aspirations and inconsistent terminology they have given me, but the results won't be what they expect and probably won't be what they want either. And that's just talking to my boss :-) If you want something specific you'll have to specify it, otherwise you'll get something else. -- Rhodri James *-* Kynesim Ltd

2018-05-09 13:48 GMT-03:00 Rhodri James <rhodri@kynesim.co.uk>:
-1 until you give me an actual spec rather than a curious example.
Sorry if that sounds a bit rude, but I spend most of my time trying to find
Be sorry, it was rude. This list is for throwing ideas and see if they gain momentum... if yes, it will be time for a PEP. I know how to do a PEP, believe me. But if we'll be asking for a Spec for every idea we think may be valuable, we'll stall. Regards, -- . Facundo Blog: http://www.taniquetil.com.ar/plog/ PyAr: http://www.python.org/ar/ Twitter: @facundobatista

On Wed, May 09, 2018 at 04:56:38PM -0300, Facundo Batista wrote:
I do not agree that Rhodri's comments were rude. They were frank and honest constructive criticism of the presentation of your idea. I have no patience with hair-trigger accusations of "rudeness" as a debating tactic to curtail criticism, and your response to Rhodri's mild and fair words looks exactly like that. Whether you intended it that way or not, that is what it looks like to me. I too spent some time scratching my head trying to guess what you expect this "j" format code to do, including the fundamental question "why j and not some other letter?". Even after I worked out some of it, I was still left with questions. So I think that Rhodri's criticism is completely valid: your post was vague, with a lack of detail and not even an attempt to provide a partial specification. That doesn't have to be a formal specification, but it should be at least an attempt to say "this is what the format code means", rather than expect people to guess from a single example. (By the way, if you answered my earlier questions, I haven't seen the answer.) Dealing with under-specified, vague instructions, and the invariable failure to guess correctly what was intended, is frustrating, annoying and painful. We should not be surprised that vague proposals can trigger an angry response, but Rhodri's post showed great restraint. It isn't just the waste of time and effort when when we guess wrong, it is also the implied disrespect: "I am too important to bother explaining myself to minions like you. Work out what I mean." If an idea is important enough to post here, we should be willing to spend some time presenting the idea in sufficient detail so that people don't have to guess what we mean. As the Zen says, "Explicit is better than implicit". No, that doesn't mean that we have to write a PEP before posting. There is a middle-ground between giving a single example and expecting people to extrapolate from it, and writing a full PEP. -- Steve

2018-05-09 21:45 GMT-03:00 Steven D'Aprano <steve@pearwood.info>:
I totally apologize if I made you, Rhodri or anybody to feel bad about this. It was not my intention to do that. It felt rude to me and I reacted badly, and too fast. I should have behaved differently, sorry again. Regards, -- . Facundo Blog: http://www.taniquetil.com.ar/plog/ PyAr: http://www.python.org/ar/ Twitter: @facundobatista

On 09/05/18 20:56, Facundo Batista wrote:
On reflection, I'm not sorry at all. It needed to be said, and attempting to deduce a spec from a single example has already caused people to go off in a variety of different directions. If provoking you into being even a bit more specific gets our collective cat herd moving in something more like the same direction, it'll be worth it. In that spirit, and trying not to take this as a challenge to see how rude I can be without actually being rude: ;-) I too didn't equate "j" with "join". I was somewhat expecting "l" for "list" given that "s" for "sequence" is taken. Should I take it that everything from the colon to the "j" is an implicitly delimited string to use for joining? If so, does anything in that string need escaping, like say braces or other "j"s? I'm not sure if format specifiers currently allow arbitrary text (I don't think they do, but I'm not sure), which might make this a more serious undertaking than it first looks. Alternatively, are certain characters forbidden in this implicit join string? I presume also that no other formatting is possible with this specifier: no field widths, no justification, none of the other stuff applicable to strings. I'm not talking about formatting the original strings (or whatever) in the list, that would clearly involve crazy amounts of sub-formatting and look like a complete mess in the code, but I can see a need for formatting the final joined string, and I can't see a way of doing that from what you've given us. I'm not convinced, I admit. Your use case
print("{title!r} (${price}) by {authors:, j}".format(**info)) "A book" ($2.34) by John, Mary, Estela
is moderately compelling, but is starting to look too magic for my tastes. I think it's the implicitly delimited join string; it isn't obvious at first sight that the comma and space aren't independently meaningful in some obscure way, like everything else in that position in a format would be.
Raising the barrier a bit is no bad thing in my opinion; it shouldn't be easy to add things to Python, otherwise we'd have a much uglier language. Regardless, there is a difference between a full-blown PEP and an outline spec. Much as I would like to have every jot and tittle in place for a first draft, I know that's not realistic and I don't expect it. On the other hand, bitter experience has taught me that when the first draft of a proposal is as nebulous as what you gave us, I should walk away from the incipient disaster right now. -- Rhodri James *-* Kynesim Ltd

On 5/10/18 7:02 AM, Rhodri James wrote:
A format spec can contain anything. Its interpretation is completely left to the type being formatted. For example, a datetime supports a strftime() string, which can be anything:
'{:today is %Y-%m-%d}'.format(datetime.datetime.now()) 'today is 2018-05-10'
In str.format(), there's a restriction that the format spec can't contain a closing brace }, but that's solely a restriction of the string scanning that's going on, and not a function of the __format__ protocol itself. For example:
format(datetime.datetime.now(), 'today is %Y-%m-%d {tada!}') 'today is 2018-05-10 {tada!}'
I always suggest to people that they don't look at f-strings or str.format() when coming up with examples, but instead use format() or obj.__format__() to more clearly see what's happening. In Facundo's original example: authors = ["John", "Mary", "Estela"] "Authors: {:, j}".format(authors) it's best to think of this as: "Authors: " + format(authors, ', j') or the equivalent (in this case): "Authors: " + authors.__format__(', j') authors is a list in this example, so list.__format__() would have to understand the format spec ', j'. Okay, that's probably doable (although I'm not advocating it!). But you really don't want this to work just for lists. What about: def authors1(): yield "John" yield "Mary" yield "Estela" format(authors1(), ', j') How would that work? Would generators grow a __format__()? It's not possible to add this functionality to every iterator past, present, and future. This is why I think a wrapper that adds a __format__(), which itself calls str.join(), is the only way to handle this. This is what I showed in my earlier response as the Join class. And at that point, I don't think it's really worth the hassle over just calling str.join(). Eric

2018-05-10 8:02 GMT-03:00 Rhodri James <rhodri@kynesim.co.uk>:
I apologize if *I* was rude or made feel you badly in any way.
Yes.
Don't know. I think I need to read this for ideas: https://mail.python.org/pipermail/python-ideas/2015-September/035789.html
I concur, joining *and* do special formatting for the elements would be a mess. That's way in other mail I said that probably cover the basic case (doing just str()) is better; if you want something more complex you always can do it as a separate step :/ -- . Facundo Blog: http://www.taniquetil.com.ar/plog/ PyAr: http://www.python.org/ar/ Twitter: @facundobatista

Facundo, I think this is the beginning of a great feature. And it fills a hole in the current string formatting. Specifically, we can carefully control the formatting of the base data types, but not collections. I would like to see you flesh out the idea. In particular, I'd like to see you address cases where: 1. The underlying members in the collection are not strings. Besides the basic types such as numbers, it would also be nice to be able to apply formats recursively so that one can construct a string using the attributes of members that are objects or items or other collections. 2. The ability to handle collections other than simple lists or iterables, such as dictionaries. -Ken On Wed, May 09, 2018 at 09:39:08AM -0300, Facundo Batista wrote:

I didn't think about this at the time. I have the feeling (not really well thought yet) that "recursive formatting" will complicate everything too much, that doing str() (as {} defaults to) on every object would fulfill most of the basic cases and keep this simple.
2. The ability to handle collections other than simple lists or iterables, such as dictionaries.
Ideally, it will handle *any* iterable. Thanks! -- . Facundo Blog: http://www.taniquetil.com.ar/plog/ PyAr: http://www.python.org/ar/ Twitter: @facundobatista

On Thu, May 10, 2018 at 11:13 PM, Facundo Batista <facundobatista@gmail.com> wrote:
If it's to handle arbitrary iterables, it can't be the normal style of "take this string, pass it to the object's __format__ method, and let it interpret it". That's why I suggested a bang notation instead. We have some already:
Those markers apply to ANY object, and pass it through str() or repr() respectively, before using any provided format string. A "!j" flag could take an iterable, format each element using the given format, and then join them. The letter "j" makes good sense then, as it parallels str.join() - this would be broadly similar to "...".join(format(...) for x in iter). ChrisA

2018-05-10 10:34 GMT-03:00 Chris Angelico <rosuav@gmail.com>:
Yes, I think it fits better, as it's not just a formatting, it's more an "operation"...
Where would you indicate the separator if we use the bang notation? Thanks! -- . Facundo Blog: http://www.taniquetil.com.ar/plog/ PyAr: http://www.python.org/ar/ Twitter: @facundobatista

On 5/10/18 12:28 PM, Facundo Batista wrote:
You would have to wedge it in before the colon. Something like: f'{lst!j, :20}' But then you couldn't have a colon in the separator. And this would be our first conversion character to be more than a single character. I'm opposed to this proposal. Just call str.join(), or write a helper function or class (depending on what you're trying to do). It's not worth complicating what's already a complicated topic. Eric

09.05.18 15:39, Facundo Batista пише:
In the case of the list of book or article authors it would be better to get "John, Mary and Estela" or "John, Mary, and Estela". In other cases "John, Mary & Estela" can be more appropriate. I mean that in real case you will need to use an external function that implements more complex algorithm for formatting a list.

On Wed, 9 May 2018 09:39:08 -0300 Facundo Batista <facundobatista@gmail.com> wrote:
-1. I hate that the format language is slowly becoming more and more crufty, leading to unreadable code. Yes, typing `", ".join(...)` is more work, but at least the end result is readable. Regards Antoine.

On Wed, May 09, 2018 at 09:39:08AM -0300, Facundo Batista wrote:
Looks interesting, but I think we need to know the semantics in more detail. For example: - if the items of the list aren't already strings, how are they converted? - do you truly mean lists *only*, or is any iterable acceptible? Here's a tiny proof-of-concept for the feature: import string class Template(string.Formatter): def format_field(self, value, spec): if spec.endswith('j'): value = ', '.join(map(str, value)) spec = spec[:-1] + 's' return super(Template, self).format_field(value, spec) Template().format('{:j} => {:d}', ['alpha', 'beta', 42, 'delta'], 99) # returns 'alpha, beta, 42, delta => 99' -- Steve

On Wed, May 9, 2018 at 11:06 PM, Steven D'Aprano <steve@pearwood.info> wrote:
I'd expect that they'd be converted using format(), which by default would just call str(). How you'd go about specifying a format string, though, I'm not sure.
- do you truly mean lists *only*, or is any iterable acceptible?
From the sound of it, this would be a change made to format(), or rather the underlying C level function, PyObject_Format(). If done
With the letter being "j" and the semantics being lifted from str.join(), I would guess the latter. there, it would also automatically apply to f-strings and anything else that calls format(). Perhaps the right way is not a colon marker, but an enhancement to the ! notation? We currently have !s and !r to do str() and repr(), and this could be !j followed by a join string. Combining this with a colon would allow the individual elements to be formatted with the given string, and then joined. For instance: x = [1,2,3] msg = '#{x:3d!j, }#'.format(x=x) # or equivalently msg = f'#{x:3d!j, }#' assert msg == '# 1, 2, 3#' +0.5 on this. I don't currently yearn for it, but I'd probably use it if it were available. ChrisA

On 5/9/18 9:28 AM, Chris Angelico wrote:
Since '{:spec}'.format(obj) basically becomes obj.__format__('spec'), this would have to be implemented on a concrete type (in the above example, list).
I would object to changing the format machinery. Any format spec should be interpreted by some object's __format__ method. Eric

On 9 May 2018 at 14:49, Eric V. Smith <eric@trueblade.com> wrote:
[...]
I would object to changing the format machinery. Any format spec should be interpreted by some object's __format__ method.
Agreed. In theory this is a nice idea, but the way formatting is implemented (and the fact that join is a method on strings taking an arbitrary iterable as an argument) means that it's a bad fit for the format mini-language. I don't think the improved convenience is sufficient to warrant the change that would be required in practice. (But if someone found a way to make it work *without* changes to the underlying format machinery, that would be a different matter...) Paul

On 5/9/18 10:01 AM, Paul Moore wrote:
Well, since you asked, let's combine this with dataclasses, because we can! from dataclasses import dataclass from typing import List @dataclass class Join: o: List[str] # or similar def __format__(self, spec): return spec.join(self.o) l = ['a', 'b'] print('{:, }'.format(Join(l))) print(f'{Join(l):-}') Gives: a, b a-b Eric

On 9 May 2018 at 15:29, Eric V. Smith <eric@trueblade.com> wrote:
:-) Sorry, I should have been clearer. Given that print('{}'.format(', '.join(l))) isn't that difficult, at least for me the attraction of the proposal was the possibility of not having to wrap the argument (whether in a function call, or in a custom class). But the print(f'{Join(l):-}') approach is certainly cleaner looking than print(f'{", ".join(l)}'). Paul

On 05/09/2018 02:39 PM, Facundo Batista wrote:
For reference (first message of a rather long previous thread): https://mail.python.org/pipermail/python-ideas/2015-September/035787.html

On 09/05/18 13:39, Facundo Batista wrote:
-1 until you give me an actual spec rather than a curious example. Sorry if that sounds a bit rude, but I spend most of my time trying to find polite ways to inform people that I'm perfectly capable of implementing the fluffy collection of vague aspirations and inconsistent terminology they have given me, but the results won't be what they expect and probably won't be what they want either. And that's just talking to my boss :-) If you want something specific you'll have to specify it, otherwise you'll get something else. -- Rhodri James *-* Kynesim Ltd

2018-05-09 13:48 GMT-03:00 Rhodri James <rhodri@kynesim.co.uk>:
-1 until you give me an actual spec rather than a curious example.
Sorry if that sounds a bit rude, but I spend most of my time trying to find
Be sorry, it was rude. This list is for throwing ideas and see if they gain momentum... if yes, it will be time for a PEP. I know how to do a PEP, believe me. But if we'll be asking for a Spec for every idea we think may be valuable, we'll stall. Regards, -- . Facundo Blog: http://www.taniquetil.com.ar/plog/ PyAr: http://www.python.org/ar/ Twitter: @facundobatista

On Wed, May 09, 2018 at 04:56:38PM -0300, Facundo Batista wrote:
I do not agree that Rhodri's comments were rude. They were frank and honest constructive criticism of the presentation of your idea. I have no patience with hair-trigger accusations of "rudeness" as a debating tactic to curtail criticism, and your response to Rhodri's mild and fair words looks exactly like that. Whether you intended it that way or not, that is what it looks like to me. I too spent some time scratching my head trying to guess what you expect this "j" format code to do, including the fundamental question "why j and not some other letter?". Even after I worked out some of it, I was still left with questions. So I think that Rhodri's criticism is completely valid: your post was vague, with a lack of detail and not even an attempt to provide a partial specification. That doesn't have to be a formal specification, but it should be at least an attempt to say "this is what the format code means", rather than expect people to guess from a single example. (By the way, if you answered my earlier questions, I haven't seen the answer.) Dealing with under-specified, vague instructions, and the invariable failure to guess correctly what was intended, is frustrating, annoying and painful. We should not be surprised that vague proposals can trigger an angry response, but Rhodri's post showed great restraint. It isn't just the waste of time and effort when when we guess wrong, it is also the implied disrespect: "I am too important to bother explaining myself to minions like you. Work out what I mean." If an idea is important enough to post here, we should be willing to spend some time presenting the idea in sufficient detail so that people don't have to guess what we mean. As the Zen says, "Explicit is better than implicit". No, that doesn't mean that we have to write a PEP before posting. There is a middle-ground between giving a single example and expecting people to extrapolate from it, and writing a full PEP. -- Steve

2018-05-09 21:45 GMT-03:00 Steven D'Aprano <steve@pearwood.info>:
I totally apologize if I made you, Rhodri or anybody to feel bad about this. It was not my intention to do that. It felt rude to me and I reacted badly, and too fast. I should have behaved differently, sorry again. Regards, -- . Facundo Blog: http://www.taniquetil.com.ar/plog/ PyAr: http://www.python.org/ar/ Twitter: @facundobatista

On 09/05/18 20:56, Facundo Batista wrote:
On reflection, I'm not sorry at all. It needed to be said, and attempting to deduce a spec from a single example has already caused people to go off in a variety of different directions. If provoking you into being even a bit more specific gets our collective cat herd moving in something more like the same direction, it'll be worth it. In that spirit, and trying not to take this as a challenge to see how rude I can be without actually being rude: ;-) I too didn't equate "j" with "join". I was somewhat expecting "l" for "list" given that "s" for "sequence" is taken. Should I take it that everything from the colon to the "j" is an implicitly delimited string to use for joining? If so, does anything in that string need escaping, like say braces or other "j"s? I'm not sure if format specifiers currently allow arbitrary text (I don't think they do, but I'm not sure), which might make this a more serious undertaking than it first looks. Alternatively, are certain characters forbidden in this implicit join string? I presume also that no other formatting is possible with this specifier: no field widths, no justification, none of the other stuff applicable to strings. I'm not talking about formatting the original strings (or whatever) in the list, that would clearly involve crazy amounts of sub-formatting and look like a complete mess in the code, but I can see a need for formatting the final joined string, and I can't see a way of doing that from what you've given us. I'm not convinced, I admit. Your use case
print("{title!r} (${price}) by {authors:, j}".format(**info)) "A book" ($2.34) by John, Mary, Estela
is moderately compelling, but is starting to look too magic for my tastes. I think it's the implicitly delimited join string; it isn't obvious at first sight that the comma and space aren't independently meaningful in some obscure way, like everything else in that position in a format would be.
Raising the barrier a bit is no bad thing in my opinion; it shouldn't be easy to add things to Python, otherwise we'd have a much uglier language. Regardless, there is a difference between a full-blown PEP and an outline spec. Much as I would like to have every jot and tittle in place for a first draft, I know that's not realistic and I don't expect it. On the other hand, bitter experience has taught me that when the first draft of a proposal is as nebulous as what you gave us, I should walk away from the incipient disaster right now. -- Rhodri James *-* Kynesim Ltd

On 5/10/18 7:02 AM, Rhodri James wrote:
A format spec can contain anything. Its interpretation is completely left to the type being formatted. For example, a datetime supports a strftime() string, which can be anything:
'{:today is %Y-%m-%d}'.format(datetime.datetime.now()) 'today is 2018-05-10'
In str.format(), there's a restriction that the format spec can't contain a closing brace }, but that's solely a restriction of the string scanning that's going on, and not a function of the __format__ protocol itself. For example:
format(datetime.datetime.now(), 'today is %Y-%m-%d {tada!}') 'today is 2018-05-10 {tada!}'
I always suggest to people that they don't look at f-strings or str.format() when coming up with examples, but instead use format() or obj.__format__() to more clearly see what's happening. In Facundo's original example: authors = ["John", "Mary", "Estela"] "Authors: {:, j}".format(authors) it's best to think of this as: "Authors: " + format(authors, ', j') or the equivalent (in this case): "Authors: " + authors.__format__(', j') authors is a list in this example, so list.__format__() would have to understand the format spec ', j'. Okay, that's probably doable (although I'm not advocating it!). But you really don't want this to work just for lists. What about: def authors1(): yield "John" yield "Mary" yield "Estela" format(authors1(), ', j') How would that work? Would generators grow a __format__()? It's not possible to add this functionality to every iterator past, present, and future. This is why I think a wrapper that adds a __format__(), which itself calls str.join(), is the only way to handle this. This is what I showed in my earlier response as the Join class. And at that point, I don't think it's really worth the hassle over just calling str.join(). Eric

2018-05-10 8:02 GMT-03:00 Rhodri James <rhodri@kynesim.co.uk>:
I apologize if *I* was rude or made feel you badly in any way.
Yes.
Don't know. I think I need to read this for ideas: https://mail.python.org/pipermail/python-ideas/2015-September/035789.html
I concur, joining *and* do special formatting for the elements would be a mess. That's way in other mail I said that probably cover the basic case (doing just str()) is better; if you want something more complex you always can do it as a separate step :/ -- . Facundo Blog: http://www.taniquetil.com.ar/plog/ PyAr: http://www.python.org/ar/ Twitter: @facundobatista

Facundo, I think this is the beginning of a great feature. And it fills a hole in the current string formatting. Specifically, we can carefully control the formatting of the base data types, but not collections. I would like to see you flesh out the idea. In particular, I'd like to see you address cases where: 1. The underlying members in the collection are not strings. Besides the basic types such as numbers, it would also be nice to be able to apply formats recursively so that one can construct a string using the attributes of members that are objects or items or other collections. 2. The ability to handle collections other than simple lists or iterables, such as dictionaries. -Ken On Wed, May 09, 2018 at 09:39:08AM -0300, Facundo Batista wrote:

I didn't think about this at the time. I have the feeling (not really well thought yet) that "recursive formatting" will complicate everything too much, that doing str() (as {} defaults to) on every object would fulfill most of the basic cases and keep this simple.
2. The ability to handle collections other than simple lists or iterables, such as dictionaries.
Ideally, it will handle *any* iterable. Thanks! -- . Facundo Blog: http://www.taniquetil.com.ar/plog/ PyAr: http://www.python.org/ar/ Twitter: @facundobatista

On Thu, May 10, 2018 at 11:13 PM, Facundo Batista <facundobatista@gmail.com> wrote:
If it's to handle arbitrary iterables, it can't be the normal style of "take this string, pass it to the object's __format__ method, and let it interpret it". That's why I suggested a bang notation instead. We have some already:
Those markers apply to ANY object, and pass it through str() or repr() respectively, before using any provided format string. A "!j" flag could take an iterable, format each element using the given format, and then join them. The letter "j" makes good sense then, as it parallels str.join() - this would be broadly similar to "...".join(format(...) for x in iter). ChrisA

2018-05-10 10:34 GMT-03:00 Chris Angelico <rosuav@gmail.com>:
Yes, I think it fits better, as it's not just a formatting, it's more an "operation"...
Where would you indicate the separator if we use the bang notation? Thanks! -- . Facundo Blog: http://www.taniquetil.com.ar/plog/ PyAr: http://www.python.org/ar/ Twitter: @facundobatista

On 5/10/18 12:28 PM, Facundo Batista wrote:
You would have to wedge it in before the colon. Something like: f'{lst!j, :20}' But then you couldn't have a colon in the separator. And this would be our first conversion character to be more than a single character. I'm opposed to this proposal. Just call str.join(), or write a helper function or class (depending on what you're trying to do). It's not worth complicating what's already a complicated topic. Eric

09.05.18 15:39, Facundo Batista пише:
In the case of the list of book or article authors it would be better to get "John, Mary and Estela" or "John, Mary, and Estela". In other cases "John, Mary & Estela" can be more appropriate. I mean that in real case you will need to use an external function that implements more complex algorithm for formatting a list.

On Wed, 9 May 2018 09:39:08 -0300 Facundo Batista <facundobatista@gmail.com> wrote:
-1. I hate that the format language is slowly becoming more and more crufty, leading to unreadable code. Yes, typing `", ".join(...)` is more work, but at least the end result is readable. Regards Antoine.
participants (14)
-
Antoine Pitrou
-
Chris Angelico
-
David Mertz
-
Eric V. Smith
-
Facundo Batista
-
Joao S. O. Bueno
-
Ken Kundert
-
Paul Moore
-
Raymond Hettinger
-
Rhodri James
-
Serhiy Storchaka
-
Steven D'Aprano
-
Terry Reedy
-
Wolfgang Maier