Re: [Python-ideas] PEP 8 update on line length

2019-02-19 Thread Nicolas Rolin
I don't think you will find an agreement to raise the number of line length
(we didn't even manage to find an agreement at my job with less than 10
people),
so I would suggest every reader not interested in the disscussion to put it
into the bin directly, as no decision will emerge from here.

That beeing said, the probable best limit should be None, and let
everyone's text editor line up the things the way people want to read them.


> If you have variables like number_of_pages_in_current_section
> you probably should consider a shorter name. Your IDE may make it easy
> to write such long names, but it doesn't make it easy to read them.
>

I understand that the writer wants to have shorter names, but why would I
want more ambigious names as a reader ?
How would you rename number_of_pages_in_current_section such that the
reader is not left wondering what does this variable represents ?


--
*Nicolas Rolin* | Data Scientist
+ 33 631992617 - nicolas.ro...@tiime.fr 


*15 rue Auber, **75009 Paris*
*www.tiime.fr <http://www.tiime.fr>*
___
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] Add "default" kwarg to list.pop()

2018-10-31 Thread Nicolas Rolin
As a user I always found a bit disurbing that dict pop method have a
default while list and set doesn't.
While it is way more computationally easy to check wether a list or a set
is empty that to check if a key is in a dict, it still create a signature
difference for no real reason (having a default to a built-in in python is
pretty standard).
It would be nice if every built-in/method of built-in type that returns a
value and raise in some case have access to a default instead of raise, and
not having to check the doc to see if it supports a default.

We could for exemple ask ourselves wether or not list.index should have a
default, as it is a method that we explecitely excpect to return a value
and might just raise instead.

2018-10-31 2:08 GMT+01:00 Steven D'Aprano :

> On Wed, Oct 31, 2018 at 02:25:25AM +0200, Serhiy Storchaka wrote:
> > 31.10.18 01:44, Giampaolo Rodola' пише:
> > >Sorry in advance if this has been proposed in the past but I couldn't
> > >find anything on python-ideas:
> > >
> > > >>> l = []
> > > >>> l.pop(default=1)
> > >1
> [...]
>
> > It is just
> >
> > l.pop() if l else default
>
> It might *do* the same thing, but it doesn't communicate the
> programmer's intention as well.
>
> {}.pop('key', default) could be written using LBYL too, but the
> intention is much clearer given an explicit default argument.
>
> The only advantage of the "if l" version is that if the default is
> expensive to calculate, we can short-circuit it.
>
>
> > or
> >
> > (l or [default]).pop()
>
> That's clever, but it is also wasteful, building a single-item list only
> to immediately pop the item out of it and throw the list away.
>
> [steve@ando ~]$ python3.5 -m timeit -s "l = []" "l.pop() if l else None"
> 1000 loops, best of 3: 0.0739 usec per loop
>
> [steve@ando ~]$ python3.5 -m timeit -s "l = []" "(l or [None]).pop()"
> 100 loops, best of 3: 0.421 usec per loop
>
>
>
> --
> Steve
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>



-- 

--
*Nicolas Rolin* | Data Scientist
+ 33 631992617 - nicolas.ro...@tiime.fr 


*15 rue Auber, **75009 Paris*
*www.tiime.fr <http://www.tiime.fr>*
___
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] Powerset

2018-10-16 Thread Nicolas Rolin
Can we get an utilisation context ?
I don't think it belongs in the stdlib alone on the basis that its output
is not linear in the size of its input (but exponential), so it explode
even for a mid-sized list, which by nature limits greatly its usage.
The question would be wether or not it is used enough to push it to
itertools, which is pretty hard to decide with no examples.

2018-10-16 10:41 GMT+02:00 Hasan Diwan :

> Pal,
> On Tue, 16 Oct 2018 at 01:36, Pål Grønås Drange 
> wrote:
> > I do however agree that there could be a powerset function there for
> convenience, but only +0.
>
> That is the best argument I could come up with to justify a
> set#powerset method. -- H
> --
> OpenPGP: https://sks-keyservers.net/pks/lookup?op=get=
> 0xFEBAD7FFD041BBA1
> If you wish to request my time, please do so using
> bit.ly/hd1AppointmentRequest.
> Si vous voudrais faire connnaisance, allez a bit.ly/hd1AppointmentRequest.
>
> Sent from my mobile device
> Envoye de mon portable
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>



-- 

--
*Nicolas Rolin* | Data Scientist
+ 33 631992617 - nicolas.ro...@tiime.fr 


*15 rue Auber, **75009 Paris*
*www.tiime.fr <http://www.tiime.fr>*
___
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] f-string "debug" conversion

2018-10-03 Thread Nicolas Rolin
As a user I would be really pleased with the change proposed, as I use
extensively use f-string in my logging (the fact that I have to evaluate
the string whatever the logger level is is not a performance hit for my
application), and usually the most readable logging format is
something akin to f"interesting_variable_name={interesting_variable_name},
big_list[:10]={big_list[:10]}".



2018-10-03 11:17 GMT+02:00 Chris Angelico :

> On Wed, Oct 3, 2018 at 7:09 PM Anders Hovmöller 
> wrote:
> >
> >
> > >> I don't really think accidents of implementation are different from
> hard requirements in Python, as it applies to alternative implementations.
> In practice if it deviates from CPython then it's broken. There is no
> language spec, there is only CPython. This has been the experience and
> approach of PyPy as far as I've understood it after having followed their
> blog over the years.
> > >>
> > >
> > > Definitely not true. There have been times when other implementors
> > > have come to python-dev and said, hey, is this part of the spec or is
> > > it an implementation detail? And the answer determines whether they
> > > care about that or not. For just a few examples:
> > >
> > > 1) Reference counting vs nondeterministic garbage collection
> > > 2) O(1) indexing/slicing of Unicode strings
> > > 3) "\N{...}" string escapes (okay, that's standardized, but optional)
> > > 4) Reuse of id() values
> > > 5) The "slots" mechanism for dunder method lookup
> > >
> > > The language spec determines, in some cases, that a CPython
> > > implementation detail has been promoted to standard. More often, it
> > > determines that other Pythons are permitted to behave differently.
> >
> > Sometimes they will come away from this list thinking they don't care
> but then their users will report bugs over and over again and they'll just
> have to do it anyway. You probably won't hear about most of those. Trees
> that fall in the forest when no one is there do in fact make a sound.
> >
>
> And sometimes, people all over the world learn to write "with
> open(...) as f:" instead of just letting f expire. There IS a language
> spec, and pretending there isn't one doesn't change that.
>
> ChrisA
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>



-- 

--
*Nicolas Rolin* | Data Scientist
+ 33 631992617 - nicolas.ro...@tiime.fr 


*15 rue Auber, **75009 Paris*
*www.tiime.fr <http://www.tiime.fr>*
___
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] Fix some special cases in Fractions?

2018-08-30 Thread Nicolas Rolin
I think you could take the implementation further and decide that any power
of Fraction(1) is Fraction(1) and any positive power of Fraction(0) is
Fraction(0).
I woudn't be shocked that Fraction(1) ** 3.7 == Fraction(1) and Fraction(0)
** 3.7 == 0.

However the implementation for Fraction(-1) seems a bit to "ad hoc", and
break some expected behavior of the powers.
For exemple in your code Fraction(-2) ** Fraction(2, 3) != Fraction(-1) **
Fraction(2, 3) * Fraction(2) ** Fraction(2, 3), whereas floats respect this.
You could change the code so that the property (a *b) ** c == a**c *b**c,
but idk how hard it is.

2018-08-30 13:31 GMT+02:00 Neil Girdhar :

> Thanks for the feedback.
>
> On Thu, Aug 30, 2018 at 7:13 AM Paul Moore  wrote:
>
>> (You're still not fixing your mail headers. Please do, it's hard to be
>> bothered responding if I keep having to fix your mails in order to do
>> so).
>>
>> On Thu, 30 Aug 2018 at 11:28, Neil Girdhar  wrote:
>> >
>> > But I'm only asking for fractional powers of -1, 0, and 1.  Is that
>> really a complex issue?
>>
>> Yes. (Even ignoring the oh-so-tempting complex number joke ;-)). As
>> has been seen here there's no agreement on the "right" choice of which
>> root of -1 to choose. Or possibly more accurately, no-one else is
>> agreeing with your suggestion that we choose a different option for
>> the case you're arguing over.
>>
>> And to be 100% precise, you asked for the results of three *very
>> specific* calculations to change. I guess you actually want something
>> more general - or are you really OK with (for example)
>> Fraction(-1,1)**Fraction(2,3) changing as you request, but
>> Fraction(-2,1)**Fraction(2,3) remaining as it currently is?
>
>
> Powers of other numbers have to keep the same behavior since in general
> those kinds of expressions don't create rational numbers.
>
>
>> You still
>> haven't clarified (no-one has particularly asked yet - you may
>> consider this a request to do so if you like) how you propose in
>> general that the result of
>>
>> Fraction(-1,1) ** Fraction(a, b)
>> and/or
>> Fraction(1,1) ** Fraction(a, b)
>> or maybe even more generally
>> Fraction(c,d) ** Fraction(a,b)
>>
>> would change. What exactly are the special cases you want to define
>> different results for? What is the process for choosing the result?
>>
>
> Here's my proposed method:
>
> class Fraction:
> def __pow__(a, b):
> """a ** b
> If b is not an integer, the result will be a float or complex
> since roots are generally irrational. If b is an integer, the
> result will be rational.
> """
> if isinstance(b, numbers.Rational):
> if b.denominator == 1:
> power = b.numerator
> if power >= 0:
> return Fraction(a._numerator ** power,
> a._denominator ** power,
> _normalize=False)
> elif a._numerator >= 0:
> return Fraction(a._denominator ** -power,
> a._numerator ** -power,
> _normalize=False)
> else:
> return Fraction((-a._denominator) ** -power,
> (-a._numerator) ** -power,
> _normalize=False)
> elif a == -1 and b.denominator % 2 == 1:
> return Fraction(-1 if b.numerator % 2 == 1 else 1)
> elif a == 0:
> if b > 0:
> return Fraction(0)
> else:
> raise ZeroDivisionError(
> "0 cannot be raised to a negative power")
> elif a == 1:
> return Fraction(1)
> else:
> # A fractional power will generally produce an
> # irrational number.
> return float(a) ** float(b)
> else:
> return float(a) ** b
>
> Compare it with https://github.com/python/cpython/blob/3.7/Lib/
> fractions.py#L448
>
>
>>
>> > You are right that the fractional power of -1 and 1 has multiple
>> values, but the fractional power of zero has a unique value.
>>
>> And that part of your proposal has not generated much controversy.
>> Maybe if you proposed only that, you might get that change made? I
>> haven't considered the ramifications of that because the di

Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Nicolas Rolin
>> Right, but we already have some special cases:
>
> In [8]: Fraction(2, 3) ** Fraction(3, 1)
> Out[8]: Fraction(8, 27)
>
> Fraction.__pow__ already tries to return Fraction objects where possible.
>


I think the main point to see here is what the scope of a built-in function
should be.
For a fraction module in the stdlib, I would expect that it handle
"symbolically" any fraction multiplication or division of fractions, and
integer power of fractions.
Those are simple and useful cases, that can arise a bit anywhere. Power of
non-integer is a way more complex issue (notably because power of a
non-integer is not a function), and returning the same output as float is
at least an honest way of dealing with those cases.

I'm not really sure a stdlib should even try do deal with that. If I want
to have a symbolic way of handling complex power of fractions, I should
import a specific math library whose specific job is to get this right (the
same way if you want to do matrix stuff you have to import numpy).


--

*Nicolas Rolin*
___
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] Fwd: grouping / dict of lists

2018-07-13 Thread Nicolas Rolin
I noticed recently that *all* examples for collection.defaultdict (
https://docs.python.org/3.7/library/collections.html#collections.defaultdict)
are cases of grouping (for an int, a list and a set) from an iterator with
a key, value output.

I wondered how common those constructions were, and what are defaultdict
used for else. So I took a little dive into a few libs to see it (std lib,
pypy, pandas, tensorflow, ..), and I saw essentially :
A) basic cases of "grouping" with a simple for loop and a
default_dict[key].append(value). I saw many kind of default factory
utilized, with list, int, set, dict, and even defaultdict(list). ex :
https://frama.link/UtNqvpvb, https://frama.link/o3Hb3-4U,
https://frama.link/dw92yJ1q, https://frama.link/1Gqoa7WM,
https://frama.link/bWswbHsU, https://frama.link/SZh2q8pS
B) cases of grouping, but where the for loop used was alimenting more than
one "grouper". pretty annoying if we want to group something. ex:
https://frama.link/Db-Ny49a, https://frama.link/bZakUR33,
https://frama.link/MwJFqh5o,
C) classes attributes initialization (grouping is done by repeatably
calling a function, so any grouping constructor will be useless here). ex :
https://frama.link/GoGWuQwR, https://frama.link/BugcS8wU
D) Sometimes you just want to defautdict inside a defauldict inside a dict
and just have fun : https://frama.link/asBNLr1g,
https://frama.link/8j7gzfA5

>From what I saw, the most useful would be to add method to a defaultdict to
fill it from an iterable, and using a grouping method adapted to the
default_factor (so __add__ for list, int and str, add for set, update for
dict and proably __add__ for anything else)

A sample code would be :

from collections import defaultdict
class groupingdict(defaultdict):
def group_by_iterator(self, iterator):
empty_element = self.default_factory()
if hasattr(empty_element, "__add__"):
for key, element in iterator:
self[key] += element
elif hasattr(empty_element, "update"):
for key, element in iterator:
self[key].update(element)
elif hasattr(empty_element, "add"):
for key, element in iterator:
self[key].add(element)
else:
raise TypeError('default factory does not support iteration')
return self

So that for example :
>groupingdict(dict).group_by_iterator(
(grouping_key, a_dict) for grouping_key, a_dict in [
(1, {'a': 'c'}),
(1, {'b': 'f'}),
(1, {'a': 'e'}),
(2, {'a': 'e'})
]
)
returns

>groupingdict(dict, {1: {'a': 'e', 'b': 'f'}, 2: {'a': 'e'}})


My implementation is garbage and There should be 2 method, one returning
the object and one modifing it, but I think it gives more leeway than just
a function returning a dict


2018-07-13 7:11 GMT+02:00 Chris Barker via Python-ideas <
python-ideas@python.org>:

> On Mon, Jul 9, 2018 at 5:55 PM, Franklin? Lee <
> leewangzhong+pyt...@gmail.com> wrote:
>
>> >> - The storage container.
>> >
>> >
>> > so this means you'r passing in a full set of storage containers? I'm a
>> vit
>> > confused by that -- if they might be pre-populated, then they would
>> need to
>> > be instance,s an you'd need to have one for every key -- how would you
>> know
>> > in advance aht you needed???
>>
>> No, I mean the mapping (outer) container. For example, I can pass in
>> an empty OrderedDict, or a dict that already contained some groups
>> from a previous call to the grouping function.
>>
>
> Sure -- that's what my prototype does if you pass a Mapping in (or use
> .update() )
>
> why not?
>
> -CHB
>
> --
>
> Christopher Barker, Ph.D.
> Oceanographer
>
> Emergency Response Division
> NOAA/NOS/OR(206) 526-6959   voice
> 7600 Sand Point Way NE   (206) 526-6329   fax
> Seattle, WA  98115   (206) 526-6317   main reception
>
> chris.bar...@noaa.gov
>
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
>


-- 

--
*Nicolas Rolin* | Data Scientist
+ 33 631992617 - nicolas.ro...@tiime.fr 


*15 rue Auber, **75009 Paris*
*www.tiime.fr <http://www.tiime.fr>*
___
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] grouping / dict of lists

2018-07-03 Thread Nicolas Rolin
2018-07-03 14:58 GMT+02:00 David Mertz :

> On Tue, Jul 3, 2018 at 2:52 AM Chris Barker via Python-ideas  
>
> What you've missed, in *several* examples is the value part of the tuple
> in your API. You've pulled out the key, and forgotten to include anything
> in the actual groups.  I have a hunch that if your API were used, this
> would be a common pitfall.
>
> I think this argues against your API and for Michael's that simply deals
> with "sequences of groupable things."  That's much more like what one deals
> with in SQL, and is familiar that way.  If the things grouped are compound
> object such as dictionaries, objects with common attributes, named tuples,
> etc. then the list of things in a group usually *does not* want the
> grouping attribute removed.
>


I agree the examples have lisp-level of brackets. However by using the fact
tuples don't need brackets and the fact we can use a list instead of an
iterable (the grouper will have to stock the whole object in memory anyway,
and if it is really big, use itertools.groupby who is designed exactly for
that)
For example
grouping(((len(word), word) for word in words))
can be written
grouping([len(word), word for word in words])

which is less "bracket issue prone".
The main advantage of having this syntax is that it gives a definition very
close to the one of a dict comprehension, which is nice considering want we
obtain is a dict (without that feature I'm not sure I will never attempt to
use this function).
And that allows us to have the same construction syntax as a dictionary,
with an iterable of (key, value) pair (
https://docs.python.org/3.7/library/stdtypes.html#dict).



>  So that was an interesting exercise -- many of those are a bit clearer
>> (or more compact) with the key function. But I also notice a pattern -- all
>> those examples fit very well into the key function pattern:
>>
>
> Yep.
>

Well those were the examples used to showcase the keyfunction in the PEP.
This is as bad as it gets for the "initialization by comprehension" syntax.



> I agree still (after all, I proposed it to Michael).  But this seems
> minor, and Guido seems not to like `collections` that much (or at least he
> commented on not using Counter ... which I personally love to use and to
> teach).
>

Actually counter is very very close to grouping (replace the append  with
starting value [] in the for loop by a += with starting value 0 and
groupping becomes a counter), so adding it to collections makes the more
sense by a long shot.

As far as I'm concerned, CHB semantics and syntax for the groupper object
does everything that is needed, and even a little bit too much.
It could be called AppendDict and just accept a (key, value) interable in
input, and instead of doing dict[key] = value as a dict does, does
dict[key] = [value] if key not in dict else dict[key] + [value]  (and
should be coded in C I guess)

-- 
Nicolas Rolin
___
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] grouping / dict of lists

2018-07-02 Thread Nicolas Rolin
My question would be : does it have to be a key function ? Can't we just
remove the "key" argument ?
Because for pretty much all the given examples, I would find my default as
readable and nearly as short as the "key" syntax :

> grouping(words, key=len)
grouping((len(word), word for word in words))

>grouping(names, key=itemgetter(0))
grouping((name_initial, name_initial+_name for name_initial, *_name in
names)

>grouping(contacts, key=itemgetter('city')
grouping((contact['city'], contact for contact in contacts)

>grouping(employees, key=itemgetter('department'))
grouping((employee['department'], employee for employee in employees)

>grouping(os.listdir('.'), key=lambda filepath:
os.path.splitext(filepath)[1])
grouping((os.path.splitext(filepath)[1]), filepath for filepath in
os.listdir('.'))

>grouping(transactions, key=lambda v: 'debit' if v > 0 else 'credit')
grouping(('debit' if v > 0 else 'credit', transaction_amount for
transaction_amount in transactions))

The code is slightly more verbose, but it is akin to filter(iterable,
function) vs (i for i in iterable if function(i)).

-- 
Nicolas Rolin

2018-07-02 11:52 GMT+02:00 Michael Selik :

> On Mon, Jul 2, 2018 at 2:32 AM Nicolas Rolin 
> wrote:
>
>> I think the current default quite weird, as it pretty much account to a
>> count() of each key (which can be useful, but not really what I except from
>> a grouping). I would prefer a default that might return an error to a
>> default that says ok and output something that is not what I might want.
>> For example the default could be such that grouping unpack tuples (key,
>> value) from the iterator and do what's expected with it (group value by
>> key). It is quite reasonable, and you have one example with (key, value) in
>> your example, and no example with the current default. It also allows to
>> use syntax of the kind
>>
>> >grouping((food_type, food_name for food_type, food_name in foods))
>>
>> which is pretty nice to have.
>>
>
> I'm of two minds on this point. First, I agree that it'd be nice to handle
> the (key, value) pair case more elegantly. It comes to mind often when
> writing examples, even if proportionally less in practice.
>
> Second, I'll paraphrase "Jakob's Law of the Internet User Experience" --
> users spend most of their time using *other* functions. Because
> itertools.groupby and other functions in Python established a standard for
> the behavior of key-functions, I want to keep that standard.
>
> Third, some classes might have a rich equality method that allows many
> interesting values to all wind up in the same group even if using the
> default "identity" key-function.
>
> Thanks for the suggestion. I'll include it in the PEP, at least for
> documenting all reasonable options.
>



-- 

--
*Nicolas Rolin* | Data Scientist
+ 33 631992617 - nicolas.ro...@tiime.fr 


*15 rue Auber, **75009 Paris*
*www.tiime.fr <http://www.tiime.fr>*
___
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] grouping / dict of lists

2018-07-02 Thread Nicolas Rolin
I think the current default quite weird, as it pretty much account to a
count() of each key (which can be useful, but not really what I except from
a grouping). I would prefer a default that might return an error to a
default that says ok and output something that is not what I might want.
For example the default could be such that grouping unpack tuples (key,
value) from the iterator and do what's expected with it (group value by
key). It is quite reasonable, and you have one example with (key, value) in
your example, and no example with the current default. It also allows to
use syntax of the kind

>grouping((food_type, food_name for food_type, food_name in foods))

which is pretty nice to have.

-- 
Nicolas Rolin



2018-07-02 9:43 GMT+02:00 Michael Selik :

> I made some heavy revisions to the PEP. Linking again for convenience.
> https://github.com/selik/peps/blob/master/pep-.rst
>
> Replying to Guido, Nick, David, Chris, and Ivan in 4 sections below.
>
>
> [Guido]
> On Fri, Jun 29, 2018 at 11:25 PM Guido van Rossum 
> wrote:
>
>> On Fri, Jun 29, 2018 at 3:23 PM Michael Selik  wrote:
>>
>>> On Fri, Jun 29, 2018 at 2:43 PM Guido van Rossum 
>>> wrote:
>>>
>>>> On a quick skim I see nothing particularly objectionable or
>>>> controversial in your PEP, except I'm unclear why it needs to be a class
>>>> method on `dict`.
>>>>
>>>
>>> Since it constructs a basic dict, I thought it belongs best as a dict
>>> constructor like dict.fromkeys. It seemed to match other classmethods like
>>> datetime.now.
>>>
>>
>> It doesn't strike me as important enough. Surely not every stdlib
>> function that returns a fresh dict needs to be a class method on dict!
>>
>
> Thinking back, I may have chosen the name "groupby" first, following
> `itertools.groupby`, SQL, and other languages, and I wanted to make a clear
> distinction from `itertools.groupby`. Putting it on the `dict` namespace
> clarified that it's returning a dict.
>
> However, naming it `grouping` allows it to be a stand-alone function.
>
> But I still think it is much better off as a helper function in itertools.
>>
> I considered placing it in the itertools module, but decided against
>>> because it doesn't return an iterator. I'm open to that if that's the
>>> consensus.
>>>
>>
>> You'll never get consensus on anything here, but you have my blessing for
>> this without consensus.
>>
>
> That feels like a success, but I'm going to be a bit more ambitious and
> try to persuade you that `grouping` belongs in the built-ins. I revised my
> draft to streamline the examples and make a clearer comparison with
> existing tools.
>
>
> [Nick]
> On Sat, Jun 30, 2018 at 2:01 AM Nick Coghlan  wrote:
>
>> I'm not sure if the draft was updated since [Guido] looked at it, but it
>
>
>> does mention that one benefit of the collections.Grouping approach is
>> being able to add native support for mapping a callable across every
>> individual item in the collection (ignoring the group structure), as
>> well as for applying aggregate functions to reduce the groups to
>> single values in a standard dict.
>>
>> Delegating those operations to the container API that way then means
>> that other libraries can expose classes that implement the grouping
>> API, but with a completely different backend storage model.
>>
>
> While it'd be nice to create a standard interface as you point out, my
> primary goal is to create an "obvious" way for both beginners and experts
> to group, classify, categorize, bucket, demultiplex, taxonomize, etc. I
> started revising the PEP last night and found myself getting carried away
> with adding methods to the Grouping class that were more distracting than
> useful. Since the most important thing is to make this as accessible and
> easy as possible, I re-focused the proposal on the core idea of grouping.
>
>
> [Ivan, Chris, David]
> On Sun, Jul 1, 2018 at 7:29 PM David Mertz  wrote:
>
>> {k:set(v) for k,v in deps.items()}
>> {k:Counter(v) for k,v in deps.items()}
>>
>
> I had dropped those specific examples in favor of generically "func(g)",
> but added them back. Your discussion with Ivan and Chris showed that it was
> useful to be specific.
>
>
> [Chris]
> On Sat, Jun 30, 2018 at 10:18 PM Chris Barker 
> wrote:
>
>> I'm really warming to the:
>> Alternate: collections.Grouping
>> version -- I really like this as a kind of custom mapping, rather than
>> "just a function" (or alternate constructor) -- and I like your point that

Re: [Python-ideas] Allow a group by operation for dict comprehension

2018-06-29 Thread Nicolas Rolin
A syntax that would work (which atm is a syntax error, and requires no new
keyword) would be

student_by_school = {school: [student] for school, student in
student_school_list, grouped=True}

with grouped=True being a modifier on the dict comprehension so that at
each iteration loop

current_dict[key] = value if key not in current_dict else current_dict[key]
+ value

This is an extremely borderline syntax (as it is perfectly legal to put
**{'grouped': True} in a dict comprehension), but it works.
It even keeps the extremely important "should look like a template of the
final object" property.

But it doesn't requires me to defines 2 lambda functions just to do the job
of a comprehension.

-- 
Nicolas Rolin


2018-06-29 4:57 GMT+02:00 Michael Selik :

> On Thu, Jun 28, 2018, 6:46 PM Nicolas Rolin 
> wrote:
>
>> The questions I should have asked In my original post was :
>> - Is splitting lists into sublists (by grouping elements) a high level
>> enough construction to be worthy of a nice integration in the comprehension
>> syntax ?
>>
>
> My intuition is no, it's not important enough to alter the syntax, despite
> being an important task.
>
> - In which case, is there a way to find a simple syntax that is not too
>> confusing ?
>>
>
> If you'd like to give it a shot, try to find something which is currently
> invalid syntax, but does not break compatibility. The latter criteria means
> no new keywords. The syntax should look nice as a single line with
> reasonably verbose variable names.
>
> One issue is that Python code is mostly 1-dimensional, characters in a
> line, and you're trying to express something which is 2-dimensional, in a
> sense. There's only so much you can do without newlines and indentation.
>



-- 

--
*Nicolas Rolin* | Data Scientist
+ 33 631992617 - nicolas.ro...@tiime.fr 


*15 rue Auber, **75009 Paris*
*www.tiime.fr <http://www.tiime.fr>*
___
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] Allow a group by operation for dict comprehension

2018-06-28 Thread Nicolas Rolin
2018-06-28 22:34 GMT+02:00 David Mertz :

> I agree with these recommendations. There are excellent 3rd party tools
> that do what you want. This is way too much to try to shoehorn into a
> comprehension.
>

There are actually no 3rd party tools that can "do what I want", because if
I wanted to have a function to do a group by, I would have taken the 5
minutes and 7 lines necessary to do so (or don't use a function and do my 3
liner).

My main point is that comprehensions in python are very powerful and you
can do pretty much any basic data manipulation that you want with it EXCEPT
when you want to "split" a list in sublists, in which case you have either
to use functions or a for loop.
You can note that with list comprehension you can flatten an iterable (from
sublists to a single list) with the [a for b in c for a in b] syntax, but
doing the inverse operation is impossible.

The questions I should have asked In my original post was :
- Is splitting lists into sublists (by grouping elements) a high level
enough construction to be worthy of a nice integration in the comprehension
syntax ?
- In which case, is there a way to find a simple syntax that is not too
confusing ?

My personal answer would be respectively "yes" and "maybe I don't know".
I was hoping to have some views on the topic, and it seemed to have a bit
sidetracked :)

-- 
Nicolas Rolin
___
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] Allow a group by operation for dict comprehension

2018-06-28 Thread Nicolas Rolin
Hi,

I use list and dict comprehension a lot, and a problem I often have is to
do the equivalent of a group_by operation (to use sql terminology).

For example if I have a list of tuples (student, school) and I want to have
the list of students by school the only option I'm left with is to write

student_by_school = defaultdict(list)
for student, school in student_school_list:
student_by_school[school].append(student)

What I would expect would be a syntax with comprehension allowing me to
write something along the lines of:

student_by_school = {group_by(school): student for school, student in
student_school_list}

or any other syntax that allows me to regroup items from an iterable.


Small FAQ:

Q: Why include something in comprehensions when you can do it in a small
number of lines ?

A: A really appreciable part of the list and dict comprehension is the fact
that it allows the developer to be really explicit about what he wants to
do at a given line.
If you see a comprehension, you know that the developer wanted to have an
iterable and not have any side effect other than depleting the iterator (if
he respects reasonable code guidelines).
Initializing an object and doing a for loop to construct it is both too
long and not explicit enough about what is intended.
It should be reserved for intrinsically complex operations, not one of the
base operation one can want to do with lists and dicts.


Q: Why group by in particular ?

A: If we take SQL queries (https://en.wikipedia.org/wiki/SQL_syntax#Queries)
as a reasonable way of seeing how people need to manipulate data on a
day-to-day basis, we can see that dict comprehensions already covers most
of the base operations, the only missing operations being group by and
having.

Q: Why not use it on list with syntax such as
student_by_school = [
school, student
for school, student in student_school_list
group by school
]
?

A: It would create either a discrepancy with iterators or a perhaps
misleading semantic (the one from itertools.groupby, which requires the
iterable to be sorted in order to be useful).
Having the option do do it with a dict remove any ambiguity and should be
enough to cover most "group by" applications.


Examples:

edible_list = [('fruit', 'orange'), ('meat', 'eggs'), ('meat', 'spam'),
('fruit', 'apple'), ('vegetable', 'fennel'), ('fruit', 'pineapple'),
('fruit', 'pineapple'), ('vegetable', 'carrot')]
edible_list_by_food_type = {group_by(food_type): edible for food_type,
edible in edible_list}

print(edible_list_by_food_type)
   {'fruit': ['orange', 'pineapple'], 'meat': ['eggs', 'spam'],
'vegetable': ['fennel', 'carrot']}


   bank_transactions = [200.0, -357.0, -9.99, -15.6, 4320.0, -1200.0]
   splited_bank_transactions = {group_by('credit' if amount > 0 else
'debit'): amount for amount in bank_transactions}

   print(splited_bank_transactions)
   {'credit': [200.0, 4320.0], 'debit': [-357.0, -9.99, -15.6, -1200.0]}



-- 
Nicolas Rolin
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/