Re: [Python-ideas] namedtuple literals [Was: RE a new namedtuple]

2017-07-30 Thread David Mertz
Yep.  DictRreader is better for my simple example. Just pointing out that
encountering attributes in different orders isn't uncommon.

On Jul 30, 2017 10:55 PM, "Chris Angelico"  wrote:

On Mon, Jul 31, 2017 at 3:41 PM, David Mertz  wrote:
>> But most of the time you always have the same attributes in the same
order
>> (think of reading a CSV for example), and this would be just a normal
tuple,
>> but with custom names for the indexes.
>
>
> You apparently live in a halcyon world of data cleanliness where CSV data
is
> so well behaved.
>
> In my world, I more typically deal with stuff like
>
> data1.csv:
> --
> name,age,salaryK
> John,39,50
> Sally,52,37
>
> data2.csv:
> --
> name,salaryK,age
> Juan,47,31
> Siu,88,66
>
>
> I'm likely to define different namedtuples for dealing with this:
>
> NameSalAge = namedtuple('NSA','name salary age')
> NameAgeSal = namedtuple('NAS','name age salary')
>
> Then later, indeed, I might ask:
>
> if employee1.salary == employee2.salary: ...
>
> And this would work even though I got the data from the different formats.

Then you want csv.DictReader and dictionary lookups.

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/
___
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] namedtuple literals [Was: RE a new namedtuple]

2017-07-30 Thread Chris Angelico
On Mon, Jul 31, 2017 at 3:41 PM, David Mertz  wrote:
>> But most of the time you always have the same attributes in the same order
>> (think of reading a CSV for example), and this would be just a normal tuple,
>> but with custom names for the indexes.
>
>
> You apparently live in a halcyon world of data cleanliness where CSV data is
> so well behaved.
>
> In my world, I more typically deal with stuff like
>
> data1.csv:
> --
> name,age,salaryK
> John,39,50
> Sally,52,37
>
> data2.csv:
> --
> name,salaryK,age
> Juan,47,31
> Siu,88,66
>
>
> I'm likely to define different namedtuples for dealing with this:
>
> NameSalAge = namedtuple('NSA','name salary age')
> NameAgeSal = namedtuple('NAS','name age salary')
>
> Then later, indeed, I might ask:
>
> if employee1.salary == employee2.salary: ...
>
> And this would work even though I got the data from the different formats.

Then you want csv.DictReader and dictionary lookups.

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/


Re: [Python-ideas] namedtuple literals [Was: RE a new namedtuple]

2017-07-30 Thread David Mertz
>
> But most of the time you always have the same attributes in the same order
> (think of reading a CSV for example), and this would be just a normal
> tuple, but with custom names for the indexes.
>

You apparently live in a halcyon world of data cleanliness where CSV data
is so well behaved.

In my world, I more typically deal with stuff like

data1.csv:
--
name,age,salaryK
John,39,50
Sally,52,37

data2.csv:
--
name,salaryK,age
Juan,47,31
Siu,88,66


I'm likely to define different namedtuples for dealing with this:

NameSalAge = namedtuple('NSA','name salary age')
NameAgeSal = namedtuple('NAS','name age salary')

Then later, indeed, I might ask:

if employee1.salary == employee2.salary: ...

And this would work even though I got the data from the different formats.


-- 
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons.  Intellectual property is
to the 21st century what the slave trade was to the 16th.
___
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] namedtuple literals [Was: RE a new namedtuple]

2017-07-30 Thread Nick Coghlan
On 31 July 2017 at 04:31, Paul Moore  wrote:
> On 30 July 2017 at 16:24, Nick Coghlan  wrote:
>> Rather than being about any changes on that front, these threads are
>> mostly about making it possible to write that first line as:
>>
>> MyNT = type(implicitly_typed_named_tuple_factory(foo=None, bar=None))
>
> Is that really true, though? There's a lot of discussion about whether
> ntuple(x=1, y=2) and ntuple(y=2, x=1) are equal (which implies they
> are the same type).

No, they're different types, because the requested field order is
different, just as if you made two separate calls to
"collections.namedtuple". If you want them to be the same type, so
that the parameter order in the second call gets ignored, then you
need to ask for that explicitly (either by using
"collections.namedtuple" directly, or by calling type() on an
implicitly typed instance), or else by keeping the field order
consistent.

> If there's any way they can be the same type, then
> your definition of MyNT above is inherently ambiguous, depending on
> whether we've previously referred to
> implicitly_typed_named_tuple_factory(bar=None, foo=None).

This is why any implicit type definition would *have* to use the field
order as given: anything else opens up the opportunity for
action-at-a-distance that changes the field order based on the order
in which instances are created. (Even without that concern, you'd also
get a problematic combinatorial expansion when searching for matching
existing field definitions as the number of field names increases)

> For me, the showstopper with regard to this whole discussion about
> ntuple(x=1, y=2) is this key point - every proposed behaviour has
> turned out to be surprising to someone (and not just in a "hmm, that's
> odd" sense, but rather in the sense that it'd almost certainly result
> in bugs as a result of misunderstood behaviour).

I suspect the only way it would make sense is if the addition was made
in tandem with a requirement that the builtin dictionary type be
insertion ordered by default.

The reason I say that is that given such a rule, it would
*consistently* be true that:

tuple(dict(x=1, y=2).items()) != tuple(dict(y=2, y=1).items())

Just as this is already reliably true in Python 3.6 today:

>>> from collections import OrderedDict
>>> x_first = tuple(OrderedDict(x=1, y=2).items())
>>> y_first = tuple(OrderedDict(y=2, x=1).items())
>>> x_first != y_first
True
>>> x_first
(('x', 1), ('y', 2))
>>> y_first
(('y', 2), ('x', 1))

In both PyPy and CPython 3.6+, that's actually true for the builtin
dict as well (since their builtin implementations are order preserving
and that's now a requirement for keyword argument and class execution
namespace handling).

That way, the invariant that folks would need to learn would just be:

ntuple(x=1, y=2) == tuple(dict(x=1, y=2).values())
ntuple(y=2, x=1) == tuple(dict(y=2, x=1).values())

rather than the current:

from collections import OrderedDict
auto_ntuple(x=1, y=2) == tuple(OrderedDict(x=1, y=2).values())
auto_ntuple(y=2, x=1) == tuple(OrderedDict(y=2, x=1).values())

(Using Python 3.6 and auto_ntuple from
https://gist.github.com/ncoghlan/a79e7a1b3f7dac11c6cfbbf59b189621#file-auto_ntuple-py
)

Cheers,
Nick.

-- 
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
___
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] namedtuple literals [Was: RE a new namedtuple]

2017-07-30 Thread Steven D'Aprano
On Sun, Jul 30, 2017 at 09:57:19PM +0300, Markus Meskanen wrote:

> So yeah, the order of the keyword arguments would matter in my case, and
> I've found it to work the best. How often do you get the keywords in a
> random order? 

"Random" order? Never.

*Arbitrary* order? All the time. That's the whole point of keyword 
arguments: you don't have to care about the order.

> And for those cases, you have SimpleNameSpace,

Which is no good for when you need a tuple.


> or you can
> just use the old namedtuple. But most of the time you always have the same
> attributes in the same order (think of reading a CSV for example), 

If you're reading from CSV, you probably aren't specifying the arguments 
by keyword, you're probably reading them and assigning by position. You 
may not even know what the columns are until you read the CSV file.

Let's think some more about reading from a CSV file. How often do you 
have three one-letter column names like "x", "y", "z"? I don't know 
about you, but for me, never. I'm more likely to have a dozen columns, 
or more, and I can't remember and don't want to remember what order 
they're supposed to be *every single time* I read a row or make a tuple 
of values.

The point of using keywords is to avoid needing to remember the order. 
If I have to remember the order, why bother naming them?

I think this proposal combines the worst of both worlds:

- like positional arguments, you have to care about the order, 
  and if you get it wrong, your code will likely silently break
  in a hard to debug way;

- and like keyword arguments, you have the extra typing of having
  to include the field names;

- but unlike keyword arguments, you have to include every single
  one, in the right order.



-- 
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/


Re: [Python-ideas] namedtuple literals [Was: RE a new namedtuple]

2017-07-30 Thread Terry Reedy

On 7/30/2017 2:57 PM, Markus Meskanen wrote:

I've been experimenting with this:

class QuickNamedTuple(tuple):

 def __new__(cls, **kwargs):
 inst = super().__new__(cls, tuple(kwargs.values()))
 inst._names = tuple(kwargs.keys())
 return inst

 def __getattr__(self, attr):
 if attr in self._names:
 return self[self._names.index(attr)]
 raise AttributeError(attr)

 def __repr__(self):
 values = []
 for i, name in enumerate(self._names):
 values.append(f'{name}={self[i]}')
 return f'({", ".join(values)})'

It's a quick scrap and probably not ideal code, but the idea is the 
point. I believe this is how the new "quick" named tuple should ideally 
work:


In: ntuple = QuickNamedTuple(x=1, y=2, z=-1)
In: ntuple
Out: (x=1, y=2, z=-1)
In: ntuple[1] == ntuple.y
Out: True
In: ntuple == (1, 2, 3)
Out: True
In: ntuple == QuickNamedTuple(z=-1, y=2, x=1)
Out: False

So yeah, the order of the keyword arguments would matter in my case, and 
I've found it to work the best. How often do you get the keywords in a 
random order? And for those cases, you have SimpleNameSpace, or you can 
just use the old namedtuple. But most of the time you always have the 
same attributes in the same order (think of reading a CSV for example), 
and this would be just a normal tuple, but with custom names for the 
indexes.


Using a name to position map:

class QuickNamedTuple(tuple):

def __new__(cls, **kwargs):
inst = super().__new__(cls, tuple(kwargs.values()))
inst._namepos = {name: i for i, name in enumerate(kwargs.keys())}
return inst

def __getattr__(self, attr):
try:
return self[self._namepos[attr]]
except KeyError:
raise AttributeError(attr) from None

def __repr__(self):
values = []
for name, i in self._namepos.items():
values.append(f'{name}={self[i]}')
return f'({", ".join(values)})'

Same outputs as above.

--
Terry Jan Reedy

___
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] namedtuple literals [Was: RE a new namedtuple]

2017-07-30 Thread Markus Meskanen
I've been experimenting with this:

class QuickNamedTuple(tuple):

def __new__(cls, **kwargs):
inst = super().__new__(cls, tuple(kwargs.values()))
inst._names = tuple(kwargs.keys())
return inst

def __getattr__(self, attr):
if attr in self._names:
return self[self._names.index(attr)]
raise AttributeError(attr)

def __repr__(self):
values = []
for i, name in enumerate(self._names):
values.append(f'{name}={self[i]}')
return f'({", ".join(values)})'

It's a quick scrap and probably not ideal code, but the idea is the point.
I believe this is how the new "quick" named tuple should ideally work:

In: ntuple = QuickNamedTuple(x=1, y=2, z=-1)
In: ntuple
Out: (x=1, y=2, z=-1)
In: ntuple[1] == ntuple.y
Out: True
In: ntuple == (1, 2, 3)
Out: True
In: ntuple == QuickNamedTuple(z=-1, y=2, x=1)
Out: False

So yeah, the order of the keyword arguments would matter in my case, and
I've found it to work the best. How often do you get the keywords in a
random order? And for those cases, you have SimpleNameSpace, or you can
just use the old namedtuple. But most of the time you always have the same
attributes in the same order (think of reading a CSV for example), and this
would be just a normal tuple, but with custom names for the indexes.

Just my two cents and thoughts from an everyday Python developer.
___
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] namedtuple literals [Was: RE a new namedtuple]

2017-07-30 Thread Paul Moore
On 30 July 2017 at 16:24, Nick Coghlan  wrote:
> Rather than being about any changes on that front, these threads are
> mostly about making it possible to write that first line as:
>
> MyNT = type(implicitly_typed_named_tuple_factory(foo=None, bar=None))

Is that really true, though? There's a lot of discussion about whether
ntuple(x=1, y=2) and ntuple(y=2, x=1) are equal (which implies they
are the same type). If there's any way they can be the same type, then
your definition of MyNT above is inherently ambiguous, depending on
whether we've previously referred to
implicitly_typed_named_tuple_factory(bar=None, foo=None).

For me, the showstopper with regard to this whole discussion about
ntuple(x=1, y=2) is this key point - every proposed behaviour has
turned out to be surprising to someone (and not just in a "hmm, that's
odd" sense, but rather in the sense that it'd almost certainly result
in bugs as a result of misunderstood behaviour).

Paul
___
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] namedtuple literals [Was: RE a new namedtuple]

2017-07-30 Thread Nick Coghlan
On 30 July 2017 at 20:03, Alex Walters  wrote:
>> -Original Message-
>> From: Python-ideas [mailto:python-ideas-bounces+tritium-
>> list=sdamon@python.org] On Behalf Of Michel Desmoulin
>> Sent: Sunday, July 30, 2017 4:19 AM
>> To: python-ideas@python.org
>> Subject: Re: [Python-ideas] namedtuple literals [Was: RE a new namedtuple]
>>
>>
>>
>> Le 29/07/2017 à 18:14, Alex Walters a écrit :
>> > My $0.02 on the entire series of nametuple threads is… there **might**
>> > be value in an immutable namespace type, and a mutable namespace type,
>> > but namedtuple’s promise is that they can be used anywhere a tuple can
>> > be used.  If passing in kwargs to create the potential replacement to
>> > namedtuple is sensitive to dict iteration order, it really isn’t a
>> > viable replacement for namedtuple.
>>
>> In Python 3.6, kwargs order is preserved and guaranteed. It's currently
>> implemented by relying on the non guaranteed dict order. But the 2 are
>> not linked. The spec does guaranty that for now on, kwargs order is
>> always preserved whether the dict order is or not.
>
> MyNT = namedtuple_replacement('MyNT', 'foo bar')
> data = {}
> data['bar'] = 8675309
> data['foo'] = 525600
>
> MyNT(*data) == (525600, 8675309)   # better be true, or else, we are 
> depending on iteration order.

Did you mean "MyNT(**data)" in the last line?

Either way, this is just normal predefined namedtuple creation, where
the field order is set when the type is defined.

Rather than being about any changes on that front, these threads are
mostly about making it possible to write that first line as:

MyNT = type(implicitly_typed_named_tuple_factory(foo=None, bar=None))
...

(While they do occasionally veer into discussing the idea of
yet-another-kind-of-data-storage-type, that is an extraordinarily
unlikely outcome)

Cheers,
Nick.

-- 
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
___
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] namedtuple literals [Was: RE a new namedtuple]

2017-07-30 Thread Alex Walters
> -Original Message-
> From: Python-ideas [mailto:python-ideas-bounces+tritium-
> list=sdamon@python.org] On Behalf Of Michel Desmoulin
> Sent: Sunday, July 30, 2017 4:19 AM
> To: python-ideas@python.org
> Subject: Re: [Python-ideas] namedtuple literals [Was: RE a new namedtuple]
> 
> 
> 
> Le 29/07/2017 à 18:14, Alex Walters a écrit :
> > My $0.02 on the entire series of nametuple threads is… there **might**
> > be value in an immutable namespace type, and a mutable namespace type,
> > but namedtuple’s promise is that they can be used anywhere a tuple can
> > be used.  If passing in kwargs to create the potential replacement to
> > namedtuple is sensitive to dict iteration order, it really isn’t a
> > viable replacement for namedtuple.
> 
> In Python 3.6, kwargs order is preserved and guaranteed. It's currently
> implemented by relying on the non guaranteed dict order. But the 2 are
> not linked. The spec does guaranty that for now on, kwargs order is
> always preserved whether the dict order is or not.

MyNT = namedtuple_replacement('MyNT', 'foo bar')
data = {}
data['bar'] = 8675309
data['foo'] = 525600

MyNT(*data) == (525600, 8675309)   # better be true, or else, we are depending 
on iteration order.


> 
> >
> >
> >
> > I do feel like there isn’t that big of a usecase for an immutable
> > namespace type as there is for a namedtuple.  I would rather namedtuple
> > class creation be quicker.
> >
> >
> >
> >
> >
> > *From:* Python-ideas
> > [mailto:python-ideas-bounces+tritium-list=sdamon@python.org] *On
> > Behalf Of *Chris Barker
> > *Sent:* Friday, July 28, 2017 8:27 PM
> > *To:* Ethan Furman 
> > *Cc:* Python-Ideas 
> > *Subject:* Re: [Python-ideas] namedtuple literals [Was: RE a new
> namedtuple]
> >
> >
> >
> > On Thu, Jul 27, 2017 at 7:42 PM, Ethan Furman  > > wrote:
> >
> > How I get the point[0] == 3?  The first definition of an ntuple had
> > the order as x, y, and since the proposal is only comparing field
> > names (not order), this (y, x) ntuple ends up being reversed to how
> > it was specified.
> >
> >
> >
> > I'm not sure there ever was a "proposal" per se, but:
> >
> > ntuple(x=a, y=b)
> >
> >
> >
> > had better be a different type than:
> >
> > ntuple(y=b, x=a)
> >
> > but first we need to decide if we want an easy way to make an
> > namedtuple-like object or a SimpleNemaspace-like object
> >
> >
> >
> > but if you are going to allow indexing by integer, then order needs to
> > be part of the definition.
> >
> >
> >
> > -CHB
> >
> >
> > --
> >
> >
> > Christopher Barker, Ph.D.
> > Oceanographer
> >
> > Emergency Response Division
> > NOAA/NOS/OR&R(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/
> >
> ___
> 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] namedtuple literals [Was: RE a new namedtuple]

2017-07-30 Thread Michel Desmoulin


Le 29/07/2017 à 18:14, Alex Walters a écrit :
> My $0.02 on the entire series of nametuple threads is… there **might**
> be value in an immutable namespace type, and a mutable namespace type,
> but namedtuple’s promise is that they can be used anywhere a tuple can
> be used.  If passing in kwargs to create the potential replacement to
> namedtuple is sensitive to dict iteration order, it really isn’t a
> viable replacement for namedtuple.

In Python 3.6, kwargs order is preserved and guaranteed. It's currently
implemented by relying on the non guaranteed dict order. But the 2 are
not linked. The spec does guaranty that for now on, kwargs order is
always preserved whether the dict order is or not.

> 
>  
> 
> I do feel like there isn’t that big of a usecase for an immutable
> namespace type as there is for a namedtuple.  I would rather namedtuple
> class creation be quicker.
> 
>  
> 
>  
> 
> *From:* Python-ideas
> [mailto:python-ideas-bounces+tritium-list=sdamon@python.org] *On
> Behalf Of *Chris Barker
> *Sent:* Friday, July 28, 2017 8:27 PM
> *To:* Ethan Furman 
> *Cc:* Python-Ideas 
> *Subject:* Re: [Python-ideas] namedtuple literals [Was: RE a new namedtuple]
> 
>  
> 
> On Thu, Jul 27, 2017 at 7:42 PM, Ethan Furman  > wrote:
> 
> How I get the point[0] == 3?  The first definition of an ntuple had
> the order as x, y, and since the proposal is only comparing field
> names (not order), this (y, x) ntuple ends up being reversed to how
> it was specified.
> 
>  
> 
> I'm not sure there ever was a "proposal" per se, but:
> 
> ntuple(x=a, y=b)
> 
>  
> 
> had better be a different type than:
> 
> ntuple(y=b, x=a)
> 
> but first we need to decide if we want an easy way to make an
> namedtuple-like object or a SimpleNemaspace-like object
> 
>  
> 
> but if you are going to allow indexing by integer, then order needs to
> be part of the definition.
> 
>  
> 
> -CHB
> 
> 
> -- 
> 
> 
> Christopher Barker, Ph.D.
> Oceanographer
> 
> Emergency Response Division
> NOAA/NOS/OR&R(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/
> 
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/