[Python-ideas] Temporary variables in comprehensions
As far as I can see, a comprehension like alist = [f(x) for x in range(10)] is better than a for-loop for x in range(10): alist.append(f(x)) because the previous one shows every element of the list explicitly so that we don't need to handle `append` mentally. But when it comes to something like [f(x) + g(f(x)) for x in range(10)] you find you have to sacrifice some readableness if you don't want two f(x) which might slow down your code. Someone may argue that one can write [y + g(y) for y in [f(x) for x in range(10)]] but it's not as clear as to show what `y` is in a subsequent clause, not to say there'll be another temporary list built in the process. We can even replace every comprehension with map and filter, but that would face the same problems. In a word, what I'm arguing is that we need a way to assign temporary variables in a comprehension. In my opinion, code like [y + g(y) for x in range(10) **some syntax for `y=f(x)` here**] is more natural than any solution we now have. And that's why I pro the new syntax, it's clear, explicit and readable, and is nothing beyond the functionality of the present comprehensions so it's not complicated. And I hope the discussion could focus more on whether we should allow assigning temporary variables in comprehensions rather than how to solve the specific example I mentioned above. ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Temporary variables in comprehensions
A generator can be a good idea, however, I wonder if it's really readable to have a `f_samples`. And the structure is the same as in [y + g(y) for y in [f(x) for x in range(10)]] if you replace the list with a generator. And it's similar for other solutions you mentioned. Well, I know that it can be quite different for everyone to determine whether a piece of code is readable or not, maybe it's wise to wait for more opinions. There's another problem that, as you distinguished the `simple` and `more complex` case, the offered solutions seem very specific, I'm not sure if there's a universal solution for every case of temporary variables in comprehensions. If not, I think it's too high cost to reject a new syntax if you need to work out a new solution every time. At 2018-02-15 17:53:21, "Evpok Padding" wrote: For simple cases such as `[y + g(y) for y in [f(x) for x in range(10)]]`, I don't really see what the issue is, if you really want to make it shorter, you can ``[y + g(y) for y in map(f,range(10))]` which is one of the rare case where I like `map` more than comprehensions. For more complex case, just define a intermediate generator along the lines ``` f_samples = (f(x) for x in range(10)) [y+g(y) for y in f_samples] ``` Which does exactly the same thing but - Is more readable and explicit - Has no memory overhead thanks to lazy evaluation (btw, you should consider generators for your nested comprenshions) While I am sometimes in the same state of mind, wishing for variables in comprehensions seems to me like a good indicator that your code needs refactoring. Best, E On 15 February 2018 at 10:32, Jamie Willis wrote: > > I +1 this at surface level; Both Haskell list comprehensions and Scala for > comprehensions have variable assignment in them, even between iterating and > this is often very useful. Perhaps syntax can be generalised as: > > [expr_using_x_and_y > for i in is > x = expr_using_i > for j in is > y = expr_using_j_and_x] > > This demonstrates the scope of each assignment; available in main result and > then every clause that follows it. > > Sorry to op who will receive twice, forgot reply to all > > On 15 Feb 2018 7:03 am, "fhsxfhsx" wrote: >> >> As far as I can see, a comprehension like >> alist = [f(x) for x in range(10)] >> is better than a for-loop >> for x in range(10): >> alist.append(f(x)) >> because the previous one shows every element of the list explicitly so that >> we don't need to handle `append` mentally. >> >> But when it comes to something like >> [f(x) + g(f(x)) for x in range(10)] >> you find you have to sacrifice some readableness if you don't want two f(x) >> which might slow down your code. >> >> Someone may argue that one can write >> [y + g(y) for y in [f(x) for x in range(10)]] >> but it's not as clear as to show what `y` is in a subsequent clause, not to >> say there'll be another temporary list built in the process. >> We can even replace every comprehension with map and filter, but that would >> face the same problems. >> >> In a word, what I'm arguing is that we need a way to assign temporary >> variables in a comprehension. >> In my opinion, code like >> [y + g(y) for x in range(10) **some syntax for `y=f(x)` here**] >> is more natural than any solution we now have. >> And that's why I pro the new syntax, it's clear, explicit and readable, and >> is nothing beyond the functionality of the present comprehensions so it's >> not complicated. >> >> And I hope the discussion could focus more on whether we should allow >> assigning temporary variables in comprehensions rather than how to solve the >> specific example I mentioned above. >> >> >> >> >> >> ___ >> Python-ideas mailing list >> Python-ideas@python.org >> https://mail.python.org/mailman/listinfo/python-ideas >> Code of Conduct: http://python.org/psf/codeofconduct/ >> > > ___ > Python-ideas mailing list > Python-ideas@python.org > https://mail.python.org/mailman/listinfo/python-ideas > Code of Conduct: http://python.org/psf/codeofconduct/ > ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Temporary variables in comprehensions
Thank you Paul, what you said is enlightening and I agree on most part of it. I'll propose two candidate syntaxs. 1. `with ... as ...` This syntax is more paralles as there would be `for` and `with` clause as well as `for` and `with` statement. However, the existing `with` statement is semantically different from this one, although similar. 2. `for ... is ...` This syntax is more uniform as the existing `for` clause make an iterator which is a special kind of variable. However, I'm afraid this syntax might be confused with `for ... in ...` as they differ only on one letter. I like the latter one better. Other proposes are absolutely welcome. And here is an example which appears quite often in my code where I think a new syntax can help a lot: Suppose I have an list of goods showing by their ids in database, and I need to transform the ids into json including information from two tables, `Goods` and `GoodsCategory`, where the first table recording `id`, `name` and `category_id` indicating which category the goods belongs to, the second table recording `id`, `name` and `type` to the categories. With the new syntax, I can write [ { 'id': goods.id, 'name': goods.name, 'category': gc.name, 'category_type': gc.type, } for goods_id in goods_id_list for goods is Goods.get_by_id(goods_id) for gc is GoodsCategory.get_by_id(goods.category_id) ] And I cannot think of any good solutions as this one without it. To generalize this case, for each element of the list, I need two temporary variables (`goods` and `gc` in my case), and each one was used twice. And reply to the two past discussions you mentioned, 1.https://mail.python.org/pipermail/python-ideas/2011-April/009863.html This mail gave a solution to modify function `f` to keep the result. The weak point is obvious, you must modify the function `f`. 2.https://mail.python.org/pipermail/python-ideas/2012-January/013468.html This mail wrote >The important thing is that you name the thing you care about before using it. >I think this is a very natural way of writing: first you give the thing you >care about a name, then you refer to it by name. However, that's a problem every comprehension faces, not a problem drawn by the new syntax. At 2018-02-15 18:08:46, "Paul Moore" wrote: >On 15 February 2018 at 05:56, fhsxfhsx wrote: >> As far as I can see, a comprehension like >> alist = [f(x) for x in range(10)] >> is better than a for-loop >> for x in range(10): >> alist.append(f(x)) >> because the previous one shows every element of the list explicitly so that >> we don't need to handle `append` mentally. > >... as long as the code inside the comprehension remains relatively >simple. It's easy to abuse comprehensions to the point where they are >less readable than a for loop, but that's true of a lot of things, so >isn't a specific problem with comprehensions. > >> But when it comes to something like >> [f(x) + g(f(x)) for x in range(10)] >> you find you have to sacrifice some readableness if you don't want two f(x) >> which might slow down your code. > >Agreed. I hit that quite often. > >> Someone may argue that one can write >> [y + g(y) for y in [f(x) for x in range(10)]] >> but it's not as clear as to show what `y` is in a subsequent clause, not to >> say there'll be another temporary list built in the process. >> We can even replace every comprehension with map and filter, but that would >> face the same problems. > >That is a workaround (and one I'd not thought of before) but I agree >it's ugly, and reduces readability. Actually, factoring out the inner >comprehension like Evpok Padding suggests: > >f_samples = (f(x) for x in range(10)) >[y+g(y) for y in f_samples] > >is very readable and effective, IMO, so it's not *that* obvious that >local names are beneficial. > >> In a word, what I'm arguing is that we need a way to assign temporary >> variables in a comprehension. > >"We need" is a bit strong here. "It would be useful to have" is >probably true for some situations. > >> In my opinion, code like >> [y + g(y) for x in range(10) **some syntax for `y=f(x)` here**] >> is more natural than any solution we now have. >> And that's why I pro the new syntax, it's clear, explicit and readable, and >> is nothing beyond the functionality of the present comprehensions so it's >> not complicated. > >The problem is that you haven't proposed an actual syntax here, just >that one should be invented. There have been discussions on this in >the past (a quick search found >https://mail.python.org/piperma
Re: [Python-ideas] Temporary variables in comprehensions
You are right and actually I sometimes did the same thing in a temporary script such as in ipython. Because in my opinion, it's not really elegant code as one may be puzzled for the list `[f(x)]`. Well, although that's quite subjective. And also I test the code and find another `for` clause can make time cost about 1.5 times in my computer, even when I optimize `[f(x)]` to a generator `(f(x), )`. Though that's not very big issue if you don't care about efficiency that much. But a temporary list or generator is redundant here. `[f(x)]` can be an alternative, but I think it is worth a new syntax. At 2018-02-15 18:11:47, "Stephan Houben" wrote: Note that you can already do: [y + g(y) for x in range(10) for y in [f(x)]] i.e. for y in [expr] does exactly what the OP wants. No new syntax needed. If you hang out on python-list , you'll soon notice that many newbies struggle already with the list comprehension syntax. It's a mini-language which is almost, but not entirely, exactly unlike normal Python code. Let's not complicate it further. Stephan 2018-02-15 10:53 GMT+01:00 Evpok Padding : For simple cases such as `[y + g(y) for y in [f(x) for x in range(10)]]`, I don't really see what the issue is, if you really want to make it shorter, you can ``[y + g(y) for y in map(f,range(10))]` which is one of the rare case where I like `map` more than comprehensions. For more complex case, just define a intermediate generator along the lines ``` f_samples = (f(x) for x in range(10)) [y+g(y) for y in f_samples] ``` Which does exactly the same thing but - Is more readable and explicit - Has no memory overhead thanks to lazy evaluation (btw, you should consider generators for your nested comprenshions) While I am sometimes in the same state of mind, wishing for variables in comprehensions seems to me like a good indicator that your code needs refactoring. Best, E On 15 February 2018 at 10:32, Jamie Willis wrote: > > I +1 this at surface level; Both Haskell list comprehensions and Scala for > comprehensions have variable assignment in them, even between iterating and > this is often very useful. Perhaps syntax can be generalised as: > > [expr_using_x_and_y > for i in is > x = expr_using_i > for j in is > y = expr_using_j_and_x] > > This demonstrates the scope of each assignment; available in main result and > then every clause that follows it. > > Sorry to op who will receive twice, forgot reply to all > > On 15 Feb 2018 7:03 am, "fhsxfhsx" wrote: >> >> As far as I can see, a comprehension like >> alist = [f(x) for x in range(10)] >> is better than a for-loop >> for x in range(10): >> alist.append(f(x)) >> because the previous one shows every element of the list explicitly so that >> we don't need to handle `append` mentally. >> >> But when it comes to something like >> [f(x) + g(f(x)) for x in range(10)] >> you find you have to sacrifice some readableness if you don't want two f(x) >> which might slow down your code. >> >> Someone may argue that one can write >> [y + g(y) for y in [f(x) for x in range(10)]] >> but it's not as clear as to show what `y` is in a subsequent clause, not to >> say there'll be another temporary list built in the process. >> We can even replace every comprehension with map and filter, but that would >> face the same problems. >> >> In a word, what I'm arguing is that we need a way to assign temporary >> variables in a comprehension. >> In my opinion, code like >> [y + g(y) for x in range(10) **some syntax for `y=f(x)` here**] >> is more natural than any solution we now have. >> And that's why I pro the new syntax, it's clear, explicit and readable, and >> is nothing beyond the functionality of the present comprehensions so it's >> not complicated. >> >> And I hope the discussion could focus more on whether we should allow >> assigning temporary variables in comprehensions rather than how to solve the >> specific example I mentioned above. >> >> >> >> >> >> ___ >> Python-ideas mailing list >> Python-ideas@python.org >> https://mail.python.org/mailman/listinfo/python-ideas >> Code of Conduct: http://python.org/psf/codeofconduct/ >> > > ___ > Python-ideas mailing list > Python-ideas@python.org > https://mail.python.org/mailman/listinfo/python-ideas > Code of Conduct: http://python.org/psf/codeofconduct/ > ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/ ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Temporary variables in comprehensions
Hi Steve, Thank you for so detailed comments. My comments also below interleaved with yours. At 2018-02-16 08:57:40, "Steven D'Aprano" wrote: >Hi fhsxfhsx, and welcome. > >My comments below, interleaved with yours. > > >On Thu, Feb 15, 2018 at 01:56:44PM +0800, fhsxfhsx wrote: > >[quoted out of order] >> And I hope the discussion could focus more on whether we should allow >> assigning temporary variables in comprehensions rather than how to >> solve the specific example I mentioned above. > >Whether or not to allow this proposal will depend on what alternate >solutions to the problem already exist, so your specific example is very >relevant. Any proposed change has to compete with existing solutions. >> >> As far as I can see, a comprehension like >> alist = [f(x) for x in range(10)] >> is better than a for-loop >> for x in range(10): >> alist.append(f(x)) >> because the previous one shows every element of the list explicitly so >> that we don't need to handle `append` mentally. > >While I personally agree with you, many others disagree. I know quite a >few experienced, competent Python programmers who avoid list >comprehensions because they consider them harder to read and reason >about. They consider a regular for-loop better precisely because you do >see the explicit call to append. > >(In my experience, those of us who get functional-programming idioms >often forget that others find them tricky.) > >The point is that list comprehensions are already complex enough that >they are difficult for many people to learn, and some people never come >to grips with them. Adding even more features comes with a cost. > >The bottom line is that it isn't clear to me that allowing local >variables inside comprehensions will make them more readable. > To be frank, I had not thought of this before. However, in my opinion, when considering adding a new syntax, we care more about the marginal cost. I mean, I think it is the functional-programming way which is tricky, but allowing a new syntax would not make things worse. Well, that's just a guess, maybe only those who are puzzled with comprehensions can give us an answer. > >> But when it comes to something like >> [f(x) + g(f(x)) for x in range(10)] > >> >> you find you have to sacrifice some readableness if you don't want two > >> >> f(x) which might slow down your code. > >The usual comments about > >> premature optimisation apply here. > >Setting a new comprehension variable > >> is not likely to be free, and may even be >more costly than calling f(x) > >> twice if f() is a cheap expression: > > [x+1 + some_func(x+1) for x in > >> range(10)] > >could be faster than > > [y + some_func(y) for x in > >> range(10) let y = x + 1] > >or whatever syntax we come up with. > It is true. But since there are still so many cases where a temporary variable is faster. Also, even without let-clause, one can write a for-loop with a temporary variable which slow down the code. So, it seems that "setting a new comprehension variable may even be more costly" does not show any uselessness of temporary variables in comprehensions. > >> Someone may argue that one can write >> [y + g(y) for y in [f(x) for x in > >> range(10)]] > >Indeed. This would be the functional-programming solution, > >> and I >personally think it is an excellent one. The only changes are that > >> I'd >use a generator expression for the intermediate value, avoiding the > >> need >to make a full list, and I would lay it out more nicely, using > >> >whitespace to make the structure more clear: > > result = [y + g(y) for y > >> in > (f(x) for x in range(10)) > ] > In my opinion, [ y + g(y) for x in range(10) let y = f(x) ] is better because it's more corresponding to a for-loop for x in range(10): y = f(x) result.append(y + g(y)) In my opinion, comprehensions are not real functional-programming because there is not even a function. Though there're similarities, map and filter are real functional-programming. Since the similarity between for-clause in comprehensions and the for-loop, I think it's better to write comprehensions more close to for-loop. I don't know but I guess maybe it can also help those who fear comprehensions better embrace them? > >> but it's not as clear as to show what `y` is in a subsequent clause, >> not to say there'll be another temporary list built in the process. > >There's no need to build the temporary list. Use a generator >comp
Re: [Python-ideas] Temporary variables in comprehensions
Thanks so much for the comments and the collect on this syntax! Comments on *previous talk* The list also mentioned some other previous proposals, so I myself search it and find that there're even more in the mailing list since 2008. https://mail.python.org/pipermail/python-ideas/2008-August/001842.html Comments on *previous talk: PEP* The PEP seems to be about an explicit temporary namespace where any objects (including functions, classes, etc.) could be held. However, I find that this syntax may not work for temporary variables in comprehensions. We might expect this syntax work like [?.y+2 for x in range(5) given: y = x+1] But notice that the proposed `given` statement here appeared in comprehensions, where syntax changes in comprehensions are needed, and nothing about this is mentioned in the PEP. What's more, the proposed syntax is a statement like `for` statement, `if` statement, rather than a for-clause or if-clause in comprehensions. In my opinion, it's not a good idea to have a statement in comprehensions. Instead, another given-clause should be added if one wants to write code like above, doing assignments in comprehensions, which can look like: [?.y+2 for x in range(5) given y = x+1] So the ? symbol seems useless here, so maybe [y+2 for x in range(5) given y = x+1] make it quite similar to the `where` syntax you proposed. So, I agree with you that it is a good idea to have a new PEP, though for a different reason. Comments on *Choice of syntax* I gave two candidate syntaxs in https://mail.python.org/pipermail/python-ideas/2008-August/001842.html, one said `for ... in ...`, another said `with ... as ...`. The first has the same problem as `for ... = ...` you proposed. And the biggest problem I think the second will face is the difference in semantic between the `with` statement and it. When it comes to `where ... = ...`, there are one possible problem I can think of. `where` is not now a keyword in Python. There are WHERE clauses in SQL, so in many modules including peewee and SQLAlchemy, `where` is an important method. The new syntax would cause quite incompatibilities. Personally I agreed with you that postfix notation would have advantage over prefix notation. Other than `where`, `with` is quite readable in my opinion. So maybe `with ... = ...` can be another candidate? Plus the `given ... = ...` I mentioned above, there are several more candidates now. Personally I perfer `with ... = ...`, because `with` is a python keyword so it would be good for backward compatibility. *About comprehensions and expressions* You gave `print(y+2 where y = x+1)` as an example, I think it should be clarified that it's not, or at least, does not look like a comprehension, but an expression. It should give an object `y+2` rather than a list or a generator. (otherwise what list can it give?) There are for-clause and if-clause for comprehensions, and if-clause (aka ternary operators) for expressions. So, In my opinion, there should be additional discuss and examples to show that it's helpful to have such syntax. For the where-clause in expressions, I think we could refer to how python handles if-clause. The following setences are legal: [x if x else 0 for x in mylist if x > 10] The following illegal: [x if x for x in mylist if x > 10] [x if x else 0 for x in mylist if x > 10 else 10] That's to say, the two kinds of if-clause, one is only used in expressions (aka `ternary operator`), the other is only used in comprehensions. They slightly differ in syntax. The where-clause might work in similar ways. Then [z+2 where z = y+1 for x in mylist where y = x+1] means [(z+2 where z=y+1) for x in mylist where y = x+1] where the parenthesis (also the part before the first `for`) is a expression, the rest is comprehension clauses. To be more accurate, the new syntax would be: test: where_test ['if' where_test 'else' test] | lambdef where_test: or_test | ( '(' or_test 'where' NAME '=' testlist_star_expr ')' ) Mandatory parenthesis in where_test is to resolve the ambiguity in code like print(y+2 where y=x+1 if x>0 else x-1 if x>1 else 0) It could be analysed like print((y+2 where y=x+1 if x>0 else x-1) if x>1 else 0) or print(y+2 where y=(x+1 if x>0 else x-1 if x>1 else 0)). I guess thektulu may have mandatory parenthesis for the same reason. I haven't check the new syntax very carefully so there might be other ambiguities. Another example is print(y+2 if x>0 else y-2 where y=x+1) with mandatory parenthesis, one must write print((y+2 if x>0 else y-2 where y=x+1)) or print(y+2 if x>0 else (y-2 where y=x+1)) However, it might still confuse many people. I wonder whether it's a good idea to have such syntax. It would be much easier to add assignments in comprehensions. comp_iter: comp_for | comp_if | comp_where comp_where: 'where' NAME '=' testlist_star_expr [comp_iter] Comments on *Goals of the new syntax* I have a real-world example in https://mail.python.org/pipermail/python-idea
Re: [Python-ideas] Dict joining using + and +=
Considering potential ambiguity, I suggest `d1.append(d2)` so we can have an additional argument saying `d1.append(d2, mode="some mode that tells how this function behaviours")`. If we are really to have the new syntax `d1 + d2`, I suggest leaving it for `d1.append(d2, mode="strict")` which raises an error when there're duplicate keys. The semantics is nature and clear when two dicts have no overlapping keys.___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Left arrow and right arrow operators
I wonder if it is necessary to add two new operators, and for me, "arrow operator" is not clearer than `+`. Could you explain why do you prefer this operator than `+`? Also -> is a symbol of propositional logic, like ∧ and ∨ , do we also need these operators as well? At 2019-03-03 22:46:24, "francismb" wrote: >Hi, >the idea here is just to add the __larrow__ and __rarrow__ operators for ><- and ->. > > >E.g. of use on dicts : d1 = {'a':1, 'b':1 } d2 = {'a':2 } d3 = d1 -> d2 d3 >{'a':1, 'b':1 } > d1 = {'a':1, 'b':1 } d2 = {'a':2 } d3 = d1 <- d2 d3 >{'a':2, 'b':1 } > >Or on bools as Modus Ponens [1] > >Or your idea/imagination here :-) > > > >Regards, >--francis > >[1] https://en.wikipedia.org/wiki/Modus_ponens > > >___ >Python-ideas mailing list >Python-ideas@python.org >https://mail.python.org/mailman/listinfo/python-ideas >Code of Conduct: http://python.org/psf/codeofconduct/ ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] dict.merge(d1, d2, ...) (Counter proposal for PEP 584)
I agree so much on your opinion that I was just to create a topic about this if you didn't. I also propose here a small modification to make it more general which adds an argument `how` (name to be discussed), telling how to merge the dicts, as many have pointed out that there could be different ways to merge dicts. So things would be like def addition_merge(key, values, exists): """ :param key: the key to merge :param values: values of dicts to merge indexed at `key` :param exists: whether each dict contains `key` """ if any(exists): return True, sum([value for exist, value in zip(exists, values) if exist]) else: return False d1.merge(d2, d3, ..., how=addition_merge) We could even have def discard(key, values, exists): return not any(exists[1:]), values[0] d1.merge(d2, how=discard) which does the same thing as proposed `d1-d2`. This would make things like d = d1.merge(iter_of_pairs) d = d1.merge(key=value) not working, but people could easily wrap a `dict()` over the iterator or key-value stuff and attach no complication. At 2019-03-05 15:39:40, "INADA Naoki" wrote: >I think some people in favor of PEP 584 just want >single expression for merging dicts without in-place update. > >But I feel it's abuse of operator overload. I think functions >and methods are better than operator unless the operator >has good math metaphor, or very frequently used as concatenate >strings. > >This is why function and methods are better: > >* Easy to search. >* Name can describe it's behavior better than abused operator. >* Simpler lookup behavior. (e.g. subclass and __iadd__) > >Then, I propose `dict.merge` method. It is outer-place version >of `dict.update`, but accepts multiple dicts. (dict.update() >can be updated to accept multiple dicts, but it's not out of scope). > >* d = d1.merge(d2) # d = d1.copy(); d.update(d2) >* d = d1.merge(d2, d3) # d = d1.copy(); d.update(d2); d2.update(d3) >* d = d1.merge(iter_of_pairs) >* d = d1.merge(key=value) > > >## Merits of dict.merge() over operator + > >* Easy to Google (e.g. "python dict merge"). >* Easy to help(dict.merge). (or dict.merge? in IPython) >* No inefficiency of d1+d2+d3+...+dN, or sum(list_of_many_dicts) >* Type of returned value is always same to d1.copy(). No issubclass, >no __iadd__. > >## Why not dict.updated()? > >sorted() is a function so it looks different from L.sort() >But d.updated() is very similar to d.update() for human eyes. > >## How about d1 - d2? > >If it is really useful, it can be implemented as method too. > >dict.discard(sequence_of_keys) > >Regards, >-- >INADA Naoki >___ >Python-ideas mailing list >Python-ideas@python.org >https://mail.python.org/mailman/listinfo/python-ideas >Code of Conduct: http://python.org/psf/codeofconduct/ ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] A directive for indentation type, stricter indentation parsing.
Just as to your example, you can try `textwrap.dedent` At 2019-03-26 00:32:26, "Mikhail V" wrote: >Not a proposal yet, but some thoughts: >I think it would help in a longer perspective if a user could >include a directive in the header of the source code file that >defines indentation character(s) for this source file. So this >source would be parsed strictly by this char (or sequence). > >E.g.: > ># indent "\t" >... > >Would force the Python parser to use exactly 1 tab for 1 indent level. > ># indent "" >... > >Would accordingly force the parser to use exactly 4 spaces for >1 indent level. > >Frankly I don't have much proof in hand for that will be a good >addition, but intuitively I suppose it would help with some possible >future features and in general, ease the development of source >processors. > >One possible example: if a potential future feature would require >a statement, and moreover require it to be indentation-aware? >Lets take e.g. a multi-line string: > >s = """ >Hello >world >""" >print (s) > >>>> > >Hello >world > > >Here it is not so intuitive (unless you already know) how the string would >be parsed (given that Python blocks are actually indentation-based). >So if one would want to try introduce a new indent-aware string type and >look into possible parsing disambiguation scenarios - it will be not an >easy task. >E.g. say one proposes a syntax for auto-unindented string block: > >s = !!! >Hello >world >print (s) >>>> >Hello >world > >(no leading newline, no leading indent in resulting string, which is a bit more >expected result IMO). > >Then it seems one can define the parsing rule unambiguously _only_ >if one has a strictly defined character sequence for the indent level >(e.g. 1 tab or 4 spaces, but not both). >Thus it seems such a directive would be a prerequisite for such feature. > >And in general, I think it could help to make automatic conversions from one >type of indentation to other easier. > > > >Mikhail >___ >Python-ideas mailing list >Python-ideas@python.org >https://mail.python.org/mailman/listinfo/python-ideas >Code of Conduct: http://python.org/psf/codeofconduct/ ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/