Hello,
It is sometimes tedious to write a dictionary in Python. For example,
def register_user(first, last, addr1, addr2): d = {'first': first, 'last': last, 'addr1': addr1, 'addr2': addr2, 'tel': '123-456-789'}
requests.post(URL, d)
The dict literal contains a lot of duplicated words and quotation marks. Using dict type looks nicer, but still verbose.
d = dict(first=first, last=last, addr1=addr1, addr2=addr2, tel='123-456-789')
With recent JavaScript, the same object can be written more easily.
d = {first, last, addr1, addr2, tel='123-456-789'}
How about adding similar syntax to Python? Like raw strings, we can add prefix letters such as '$' to the opening curly brace for the purpose.
d = ${first, last, addr1, addr2, tel='123-456-789'}
Keys should be valid identifier strings. Other keys raise SyntaxError.
I wrote a simple POC implementation here. It looks working.
https://github.com/atsuoishimoto/cpython/pull/2
(I prefer to use `j` for the prefix over `$`, but I may need to study the parser more to use an ASCII letter as token.)
Hi there!
This request is a close cousin of the recent discussion about optional keywords arguments, which you can find in the archives at https://mail.python.org/archives/list/python-ideas@python.org/thread/MILIX6H... A lot of the same comments for and against apply here. I'll just cherry-pick a specific point:
On 09/06/2020 14:45, Atsuo Ishimoto wrote:
How about adding similar syntax to Python? Like raw strings, we can add prefix letters such as '$' to the opening curly brace for the purpose.
d = ${first, last, addr1, addr2, tel='123-456-789'}
Python is not Perl. By that I mean Python in general tends not to use non-alphanumeric symbols unless they already have a well established meaning (such as quote marks, arithmetic operators and so on). "${...}" definitely does not have such a meaning; a newcomer looking at the above would not have a lot of guidance as to what might be going on, and could be forgiven for thinking they were looking at some weird form of set.
Executive summary:
Dicts are unordered, so we can distinguish dict from set by the first item (no new notation), and after that default identifiers to (name : in-scope value) items. Also some notational bikeshedding.
Atsuo Ishimoto writes:
It is sometimes tedious to write a dictionary in Python. For example,
def register_user(first, last, addr1, addr2): d = {'first': first, 'last': last, 'addr1': addr1, 'addr2': addr2, 'tel': '123-456-789'} requests.post(URL, d)
In this particular case,
def register_user(first, last, addr1, addr2): d = locals().copy() # .copy is unnecessary in this case, # but note that the next line may # pollute the locals d['tel'] = '123-456-789'
requests.post(URL, d)
DTRTs. How often would locals() be usable in this way? Note: in the case of requests, this might be a vulnerability, because the explicit dict display would presumably include only relevant items, while locals() might inherit private credentials from the arguments, which need to be explicitly del'ed from d.
The dict literal contains a lot of duplicated words and quotation marks. Using dict type looks nicer, but still verbose.
d = dict(first=first, last=last, addr1=addr1, addr2=addr2, tel='123-456-789')
With recent JavaScript, the same object can be written more easily.
d = {first, last, addr1, addr2, tel='123-456-789'}
How about adding similar syntax to Python? Like raw strings, we can add prefix letters such as '$' to the opening curly brace for the purpose.
I understand that this was done for ease of your POC implementatation, and you prefer a letter. But I'd like to emphasize: Please don't use $ for this. Among other things, it is both in appearance and historically based on "S" for "set"!
Also, please use dict display syntax (':' not '=').
If you're going to use prefix characters, I suggest 'd' for "dict", and maybe 's' for "set" as well (to allow the use case 's{}' for the empty set, though that's not terribly useful vs. set(). I'm mostly proposing it so I be the first to say "-1" on 's{}'. :-)
This proposal does make me a more sympathetic to such abbreviations. I'm still at best +0 on it, though.
It occurs to me there's an alternative syntax with even less notation:
d = {'tel' : '123-456-789', first, last, addr1, addr2}
I.e, if the first member of the display is a dict item, it's a dict, and the rest of the members default to key = name of identifier and value = value of identifier. If 'tel' weren't a key in d you'd write
d = {'first' : first, last, addr1, addr2}
A little awkward, but in many cases you'll be adding information as you did.
I wrote a simple POC implementation here. It looks working.
Thank you!
On Wed, Jun 10, 2020 at 1:15 PM Stephen J. Turnbull turnbull.stephen.fw@u.tsukuba.ac.jp wrote:
Executive summary:
Dicts are unordered, so we can distinguish dict from set by the first item (no new notation), and after that default identifiers to (name : in-scope value) items. Also some notational bikeshedding.
Be careful with this assumption. Python's dictionaries DO retain order, even if you can't easily talk about "the fifth element" [1], so anything that imposes requirements on the entry listed syntactically first may have consequences.
ChrisA
[1] which, as we all know, is Boron
Chris Angelico writes:
On Wed, Jun 10, 2020 at 1:15 PM Stephen J. Turnbull turnbull.stephen.fw@u.tsukuba.ac.jp wrote:
Executive summary:
Dicts are unordered, so we can distinguish dict from set by the first item (no new notation), and after that default identifiers to (name : in-scope value) items.
Be careful with this assumption. Python's dictionaries DO retain order,
Thank you for the reminder! I did forget that point.
even if you can't easily talk about "the fifth element" [1], so anything that imposes requirements on the entry listed syntactically first may have consequences.
No requirements imposed! If iteration order matters and you want to take advantage of abbreviation, you might have to write
d = {first : first, last, addr1, addr2, tel='123-456-789'}
but frequently it would just work naturally:
d = {first : first, last, addr1, addr2}
Admittedly this distinction may be even more subtle than grit on Tim's screen, or randomizing the hash seed per process. And I suspect that people who want this feature will prefer the d{} notation for consistency inside the braces.
Steve
Hi Thank you for comments
2020年6月10日(水) 0:11 Rhodri James rhodri@kynesim.co.uk:
Python is not Perl. By that I mean Python in general tends not to use non-alphanumeric symbols unless they already have a well established meaning (such as quote marks, arithmetic operators and so on).
Yeah, I don't think '${...}' is appearing, too. As I wrote, it was chosen for implementation reasons. I'm open for other syntax options.
I'm curious what you think about another way to construct dictionaries.
Hi Thank you for comments
2020年6月10日(水) 12:12 Stephen J. Turnbull turnbull.stephen.fw@u.tsukuba.ac.jp:
DTRTs. How often would locals() be usable in this way? Note: in the case of requests, this might be a vulnerability, because the explicit dict display would presumably include only relevant items, while locals() might inherit private credentials from the arguments, which need to be explicitly del'ed from d.
And in case of locals() is useful, the code may eventually become unsafe someday later.
I understand that this was done for ease of your POC implementatation, and you prefer a letter. But I'd like to emphasize: Please don't use $ for this. Among other things, it is both in appearance and historically based on "S" for "set"!
I don't like it, either. But choice of valid letters are limited to such as “$", "'" and "?". So I think '$' is the best choice among these letters ;)
Also, please use dict display syntax (':' not '=').
Ah, this is a typo. I use ':' in my implementation.
If you're going to use prefix characters, I suggest 'd' for "dict", and maybe 's' for "set" as well (to allow the use case 's{}' for the empty set, though that's not terribly useful vs. set(). I'm mostly proposing it so I be the first to say "-1" on 's{}'. :-)
'd{}' would be a nice choice.
It occurs to me there's an alternative syntax with even less notation:
d = {'tel' : '123-456-789', first, last, addr1, addr2}
This is acceptable, but I prefer prefixed dict better.
Or, instead of prefixing a letter, we may be able to omit the key of items inside dict display.
d = {:name, :addr, ’tel': '123-4567’}
Thoughts?
On 10/06/2020 16:38, Atsuo Ishimoto wrote:
Hi Thank you for comments
2020年6月10日(水) 0:11 Rhodri James rhodri@kynesim.co.uk:
Python is not Perl. By that I mean Python in general tends not to use non-alphanumeric symbols unless they already have a well established meaning (such as quote marks, arithmetic operators and so on).
Yeah, I don't think '${...}' is appearing, too. As I wrote, it was chosen for implementation reasons. I'm open for other syntax options.
I'm curious what you think about another way to construct dictionaries.
Personally I just accept the repetition. It doesn't generally happen often to me, and I'd much rather be explicit.
Thank you.
It unfortunately happens to me mostly while I'm working for REST web servers, especially when writing JSON in the test suites for the app.
2020年6月11日(木) 1:24 Rhodri James rhodri@kynesim.co.uk:
On 10/06/2020 16:38, Atsuo Ishimoto wrote:
Hi Thank you for comments
2020年6月10日(水) 0:11 Rhodri James rhodri@kynesim.co.uk:
Python is not Perl. By that I mean Python in general tends not to use non-alphanumeric symbols unless they already have a well established meaning (such as quote marks, arithmetic operators and so on).
Yeah, I don't think '${...}' is appearing, too. As I wrote, it was chosen for implementation reasons. I'm open for other syntax options.
I'm curious what you think about another way to construct dictionaries.
Personally I just accept the repetition. It doesn't generally happen often to me, and I'd much rather be explicit.
-- Rhodri James *-* Kynesim Ltd
I find this interesting, another solution would be for locals() to take arguments:
dict(tel='1337-1337', **locals('name', 'surname'))
Stephen J. Turnbull
d = {first : first, last, addr1, addr2}
I'm not a huge fan of this solution. It feels a bit like a hack instead of an intended syntax. Since prefixing characters on strings is already a thing, I lean more towards that solution. It's slightly easier to search (e.g. if the notation was d{literal1, literal2, etc}, one might search for "python d-dict"). However, If the above notation gains favor, perhaps it would be better to allow an empty ':' followed by a comma:
d = {:, first, last, addr1, addr2}
I don't much like the Perlyness of that syntax, but it's similar to using a prefix and it might lead to more explicit empty literals like {:} and {,} for dict and set respectively. I'm pretty sure that notation for empty literals has been discussed and rejected before, so I apologize if this brings up well-trodden ground. I'm pretty neutral on the proposal in general.
It may also be possible to add a constructor to dict like:
d = dict.from_locals('first', 'last', 'addr1', 'addr2') d['tel'] = '123-456-789'
It might require a bit of stack inspection or some other magic, but it should be possible. It might be difficult for IDEs to recognize and hint and it might also be a blind-spot for re-factoring (if you change the name of a local variable).
On Wed, Jun 10, 2020 at 3:06 AM Stephen J. Turnbull < turnbull.stephen.fw@u.tsukuba.ac.jp> wrote:
Chris Angelico writes:
On Wed, Jun 10, 2020 at 1:15 PM Stephen J. Turnbull turnbull.stephen.fw@u.tsukuba.ac.jp wrote:
Executive summary:
Dicts are unordered, so we can distinguish dict from set by the first item (no new notation), and after that default identifiers to (name : in-scope value) items.
Be careful with this assumption. Python's dictionaries DO retain order,
Thank you for the reminder! I did forget that point.
even if you can't easily talk about "the fifth element" [1], so anything that imposes requirements on the entry listed syntactically first may have consequences.
No requirements imposed! If iteration order matters and you want to take advantage of abbreviation, you might have to write
d = {first : first, last, addr1, addr2, tel='123-456-789'}
but frequently it would just work naturally:
d = {first : first, last, addr1, addr2}
Admittedly this distinction may be even more subtle than grit on Tim's screen, or randomizing the hash seed per process. And I suspect that people who want this feature will prefer the d{} notation for consistency inside the braces.
Steve _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/ENXYVR... Code of Conduct: http://python.org/psf/codeofconduct/
I like Atsou's suggestion of omitting the key for literals:
d = {:name, :addr, ’tel': '123-4567’}
but using empty kwargs feels gross:
d = dict(=name, =addr, tel='123-456')
And this feels like it could easily lead to confusion:
d = dict(name, addr, tell='123-456')
On Thu, Jun 11, 2020 at 4:05 PM Abe Dillon abedillon@gmail.com wrote:
Stephen J. Turnbull
d = {first : first, last, addr1, addr2}
I'm not a huge fan of this solution. It feels a bit like a hack instead of an intended syntax. Since prefixing characters on strings is already a thing, I lean more towards that solution. It's slightly easier to search (e.g. if the notation was d{literal1, literal2, etc}, one might search for "python d-dict"). However, If the above notation gains favor, perhaps it would be better to allow an empty ':' followed by a comma:
d = {:, first, last, addr1, addr2}
I don't much like the Perlyness of that syntax, but it's similar to using a prefix and it might lead to more explicit empty literals like {:} and {,} for dict and set respectively. I'm pretty sure that notation for empty literals has been discussed and rejected before, so I apologize if this brings up well-trodden ground. I'm pretty neutral on the proposal in general.
It may also be possible to add a constructor to dict like:
d = dict.from_locals('first', 'last', 'addr1', 'addr2') d['tel'] = '123-456-789'
It might require a bit of stack inspection or some other magic, but it should be possible. It might be difficult for IDEs to recognize and hint and it might also be a blind-spot for re-factoring (if you change the name of a local variable).
On Wed, Jun 10, 2020 at 3:06 AM Stephen J. Turnbull < turnbull.stephen.fw@u.tsukuba.ac.jp> wrote:
Chris Angelico writes:
On Wed, Jun 10, 2020 at 1:15 PM Stephen J. Turnbull turnbull.stephen.fw@u.tsukuba.ac.jp wrote:
Executive summary:
Dicts are unordered, so we can distinguish dict from set by the first item (no new notation), and after that default identifiers to (name : in-scope value) items.
Be careful with this assumption. Python's dictionaries DO retain order,
Thank you for the reminder! I did forget that point.
even if you can't easily talk about "the fifth element" [1], so anything that imposes requirements on the entry listed syntactically first may have consequences.
No requirements imposed! If iteration order matters and you want to take advantage of abbreviation, you might have to write
d = {first : first, last, addr1, addr2, tel='123-456-789'}
but frequently it would just work naturally:
d = {first : first, last, addr1, addr2}
Admittedly this distinction may be even more subtle than grit on Tim's screen, or randomizing the hash seed per process. And I suspect that people who want this feature will prefer the d{} notation for consistency inside the braces.
Steve _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/ENXYVR... Code of Conduct: http://python.org/psf/codeofconduct/
Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/F2DDRM... Code of Conduct: http://python.org/psf/codeofconduct/
instead of prefixing a letter, we may be able to omit the key of items inside dict display.
d = {:name, :addr, ’tel': '123-4567’}
This is my favorite variation on the notation so far. I'll give it a +1
On Wed, Jun 10, 2020 at 10:49 AM Atsuo Ishimoto ishimoto@python.jp wrote:
Hi Thank you for comments
2020年6月10日(水) 12:12 Stephen J. Turnbull < turnbull.stephen.fw@u.tsukuba.ac.jp>:
DTRTs. How often would locals() be usable in this way? Note: in the case of requests, this might be a vulnerability, because the explicit dict display would presumably include only relevant items, while locals() might inherit private credentials from the arguments, which need to be explicitly del'ed from d.
And in case of locals() is useful, the code may eventually become unsafe someday later.
I understand that this was done for ease of your POC implementatation, and you prefer a letter. But I'd like to emphasize: Please don't use $ for this. Among other things, it is both in appearance and historically based on "S" for "set"!
I don't like it, either. But choice of valid letters are limited to such as “$", "'" and "?". So I think '$' is the best choice among these letters ;)
Also, please use dict display syntax (':' not '=').
Ah, this is a typo. I use ':' in my implementation.
If you're going to use prefix characters, I suggest 'd' for "dict", and maybe 's' for "set" as well (to allow the use case 's{}' for the empty set, though that's not terribly useful vs. set(). I'm mostly proposing it so I be the first to say "-1" on 's{}'. :-)
'd{}' would be a nice choice.
It occurs to me there's an alternative syntax with even less notation:
d = {'tel' : '123-456-789', first, last, addr1, addr2}
This is acceptable, but I prefer prefixed dict better.
Or, instead of prefixing a letter, we may be able to omit the key of items inside dict display.
d = {:name, :addr, ’tel': '123-4567’}
Thoughts? _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/6Y3NSE... Code of Conduct: http://python.org/psf/codeofconduct/