Re: Which more Pythonic - self.__class__ or type(self)?

2023-03-03 Thread Alan Gauld
On 02/03/2023 20:54, Ian Pilcher wrote:
> Seems like an FAQ, and I've found a few things on StackOverflow that
> discuss the technical differences in edge cases, but I haven't found
> anything that talks about which form is considered to be more Pythonic
> in those situations where there's no functional difference.

I think avoiding dunder methods is generally considered more Pythonic.

But in this specific case using isinstance() is almost always
the better option. Testing for a specific class is likely to break
down in the face of subclasses. And in Python testing for static types
should rarely be necessary since Python uses duck typing
and limiting things to a hard type seriously restricts your code.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Which more Pythonic - self.__class__ or type(self)?

2023-03-03 Thread Chris Angelico
On Fri, 3 Mar 2023 at 20:44, Alan Gauld  wrote:
>
> On 02/03/2023 20:54, Ian Pilcher wrote:
> > Seems like an FAQ, and I've found a few things on StackOverflow that
> > discuss the technical differences in edge cases, but I haven't found
> > anything that talks about which form is considered to be more Pythonic
> > in those situations where there's no functional difference.
>
> I think avoiding dunder methods is generally considered more Pythonic.
>
> But in this specific case using isinstance() is almost always
> the better option. Testing for a specific class is likely to break
> down in the face of subclasses. And in Python testing for static types
> should rarely be necessary since Python uses duck typing
> and limiting things to a hard type seriously restricts your code.
>

Using isinstance is very different from querying the type of an object
though. They're used for different purposes. And obj.__class__ and
type(obj) are different too, which is why the OP specifically narrowed
this down to the situations where you know they're the same.

Personally, I'd probably use type(obj) if the distinction doesn't
matter, but that's nothing more than personal preference.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Python list insert iterators

2023-03-03 Thread Guenther Sohler
Hi Python community,

I have a got an example list like

1,  2,  3, 4, 5, 6, 7, 8, 9, 10
T   T

and i  eventually want to insert items in the given locations
(A shall go between 2 and 3,  B shall go between 6 and 7)

Right now i just use index numbers to define the place:

A shall insert in position 2
B shall insert in position 6

However when i insert A in position 2, the index for successful insertion
of B gets wrong
(should now be 7 instead of 6)

No, it's not an option to sort the indexes and start inserting from the
back.
The most elegant option is not to store indexes, but list iterators, which
attach to the list element
and would automatically move, especially if an element is inserted before.

I could not find such functionality in python lists of [ 1,2,3 ]

Does python have such functionality ?
if yes, where can i find it ?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Which more Pythonic - self.__class__ or type(self)?

2023-03-03 Thread Ethan Furman

On 3/3/23 03:32, Chris Angelico wrote:
> On Fri, 3 Mar 2023 at 20:44, Alan Gauld wrote:
>> On 02/03/2023 20:54, Ian Pilcher wrote:

>>> Seems like an FAQ, and I've found a few things on StackOverflow that
>>> discuss the technical differences in edge cases, but I haven't found
>>> anything that talks about which form is considered to be more Pythonic
>>> in those situations where there's no functional difference.
>>
>> I think avoiding dunder methods is generally considered more Pythonic.

Outside of writing dunder methods, I tend to agree.

>> But in this specific case using isinstance() is almost always
>> the better option.

True.  IIRC, the only time I haven't used `isinstance` is in `Enum`, where a particular object has to be exactly a tuple 
(not a namedtuple, for example) to work correctly.


> Using isinstance is very different from querying the type of an object
> though. They're used for different purposes. And obj.__class__ and
> type(obj) are different too, which is why the OP specifically narrowed
> this down to the situations where you know they're the same.

When writing classes and subclasses, I use `obj.__class__`, `isinstance` otherwise, and rarely `type(obj)` (and then 
mostly with `tuple`s, as they're special).


~Ethan~
--
https://mail.python.org/mailman/listinfo/python-list


Re: Python list insert iterators

2023-03-03 Thread Thomas Passin

On 3/3/2023 3:22 AM, Guenther Sohler wrote:

Hi Python community,

I have a got an example list like

1,  2,  3, 4, 5, 6, 7, 8, 9, 10
 T   T

and i  eventually want to insert items in the given locations
(A shall go between 2 and 3,  B shall go between 6 and 7)

Right now i just use index numbers to define the place:

A shall insert in position 2
B shall insert in position 6

However when i insert A in position 2, the index for successful insertion
of B gets wrong
(should now be 7 instead of 6)

No, it's not an option to sort the indexes and start inserting from the
back.
The most elegant option is not to store indexes, but list iterators, which
attach to the list element
and would automatically move, especially if an element is inserted before.

I could not find such functionality in python lists of [ 1,2,3 ]

Does python have such functionality ?
if yes, where can i find it ?


You should be more clear about how to establish the desired insertion 
point.  In your example, you first say that the insertion of B should be 
between 6 and 7. But after A gets inserted, you say that B's insertion 
point should change.  How is anyone able to know what the correct 
insertion point should be at any time?


If the rule is that B should get inserted after a particular known 
element, you can find out the index of that element with list.index() 
and insert just after that. If the rule is "There is an imaginary 
location that starts out after index 6 but moves depending on previous 
insertions", then you will probably need to capture a record of those 
insertions and use it to adjust the invisible insertion point.  But this 
synchronization could be tricky to keep correct depending on what you 
want to do to this list.


So you need to specify clearly what the rules are going to be.
--
https://mail.python.org/mailman/listinfo/python-list


RE: Which more Pythonic - self.__class__ or type(self)?

2023-03-03 Thread avi.e.gross


Alan,

I do not buy into any concept about something being pythonic or not.

Python has grown too vast and innovated quite a  bit, but also borrowed from
others and vice versa.

There generally is no universally pythonic way nor should there be. Is there
a C way and then a C++ way and an R way or JavaScript or does only python a
language with a philosophy of what is the pythonic way?

My vague impression was that the pythonic way was somewhat of a contrast to
the way a programmer did it before coming to python. So some would argue
that although python allows loops, that some things are more naturally done
in python using a list comprehension.

Really?

I suggest that NOW for some people, it is way more natural to import modules
like numpy and pandas and use their tools using a more vectorized approach.
Is that the new pythonic in some situations?

I can also argue that if you were a contestant on Jeopardy and were in a
category for computer languages and were shown some computer code  and asked
to name that language in 4 lines, then the most pythonic would not be one
saying type(var) but the one showing a dunder method! I mean what makes some
languages special is often the underlying details! On the surface, many look
fairly similar.

Some problems not only can be solved many ways in python, but by using
combinations of different programming paradigms. It can be argued by some
that the pythonic way is to use some forms of object-oriented programming
and by others pushing for a more functional approach. Some seem to continue
pushing for efficiency and others relish at using up CPU cycles and prefer
other considerations such as what is easier for the programmer or that is
more self-documenting.

My answer remains, in this case, like yours. The dunder methods are
generally meant to be implementation details mostly visible when creating
new classes or perhaps adjusting an object. They largely implement otherwise
invisible protocols by providing the hooks the protocols invoke, and do it
in a somewhat reserved name space. If the user is writing code that just
uses existing classes, generally no dunderheads should be seen. I think
using them is not only not pythonic, but risks breaking code if some changes
to python are made.  As one example, the iteration protocol now has new
dunder methods added to be used for asynchronous and calling the __iter__()
type methods will not work well and you now need to know to call the new
ones. Or, don't call them at all and use the regular functions provided.

Some things may be clearly more in the spirit of the language and sometimes
who cares. Consider the debate that since python allows you to fail and
catch an exception, why bother using if statements such as checking for
no-zero before dividing. I never understood that. Plan A works. Now you can
also chose plan B. They both work. But has anyone asked some dumb questions
about the data the code is working on? What if you have data full of zeroes
or NA or Inf or other things make a division problematic. What is the cost
of testing for something or a group of things every time versus setting up a
try/catch every time? What about lots of nesting of these things. What can
humans read better or make adjustments to?

In my mind, if the bad thing you want to avoid is rare and the testing is
costly, perhaps the exception method is best. I mean if you are working with
large numbers where primes are not common, then having to test if it is a
prime can be costly while catching a failure may be less so.

But consider how some people act as if pythonic means you should not care
about efficiency! LOL!

I leave you with the question of the day. Was Voldemort pythonic?

Avi


-Original Message-
From: Python-list  On
Behalf Of Alan Gauld
Sent: Friday, March 3, 2023 4:43 AM
To: python-list@python.org
Subject: Re: Which more Pythonic - self.__class__ or type(self)?

On 02/03/2023 20:54, Ian Pilcher wrote:
> Seems like an FAQ, and I've found a few things on StackOverflow that
> discuss the technical differences in edge cases, but I haven't found
> anything that talks about which form is considered to be more Pythonic
> in those situations where there's no functional difference.

I think avoiding dunder methods is generally considered more Pythonic.

But in this specific case using isinstance() is almost always
the better option. Testing for a specific class is likely to break
down in the face of subclasses. And in Python testing for static types
should rarely be necessary since Python uses duck typing
and limiting things to a hard type seriously restricts your code.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


-- 
https://mail.python.org/mailman/listinfo/python-list

-- 
https://mail.python.org/mailman/listinfo/python-list


RE: Python list insert iterators

2023-03-03 Thread avi.e.gross
Thomas is correct that this is a bit of an odd request unless explained
better.

There are a number of implicit assumptions that need to be revisited here.
Python Lists are what they are. They are not in any way tagged. They are not
linked lists or binary trees or dictionaries or whatever you are looking
for.

They are a mutable object with an order at any given time and no memory or
history of an earlier status.

They support not just insertion but also deletion and replacement and other
things.

But generally, if your time span between deciding on additions and
implementing them will contain no deletions, then one simple solution is to
re-order your insertion to always do the last one first. The indices will
only change at and above an insertion point. Your remaining insertions will
always be at an untouched region where the indices remain the same, for now.

A second choice as Thomas points out is to adjust your indices. An example
might be if you have a collection of proposed insertions and each contains
an index number and payload. Each time you insert the next payload at the
insertion point, you invoke a function that goes through your remaining
Collection and finds any with an index that is higher and increments it.

Obviously there are issues if dealing with adding multiple times to the same
index or adding multiple items at once.

The above could be encapsulated in some kind of VIEW in some languages
including of course some that use pointers.

I will add by pointing out a way to do a multi-insertion at once if you know
all the insertions at the same time.

Take your list that you want to change by adding at say positions 9, 3 and
6.

Now DON"T insert anything. Forget the concept.

Instead, and this is drastic, make a NEW list.

The new list is loosely old[0:2] + new_at_3 + old[3:5] + new_at_6 + old[6:8]
+new_at_9 + old[9:]

Something carefully written like that using concatenation means you do not
lose track of indices and end up with a new extended list you can feel free
to save under the old name and let the prior one be garbage collected.

Maybe one of the above hints at what could work for you, or others may
supply a better answer, or maybe you reevaluate what you are doing or
explain it some more.

-Original Message-
From: Python-list  On
Behalf Of Thomas Passin
Sent: Friday, March 3, 2023 1:04 PM
To: python-list@python.org
Subject: Re: Python list insert iterators

On 3/3/2023 3:22 AM, Guenther Sohler wrote:
> Hi Python community,
> 
> I have a got an example list like
> 
> 1,  2,  3, 4, 5, 6, 7, 8, 9, 10
>  T   T
> 
> and i  eventually want to insert items in the given locations
> (A shall go between 2 and 3,  B shall go between 6 and 7)
> 
> Right now i just use index numbers to define the place:
> 
> A shall insert in position 2
> B shall insert in position 6
> 
> However when i insert A in position 2, the index for successful insertion
> of B gets wrong
> (should now be 7 instead of 6)
> 
> No, it's not an option to sort the indexes and start inserting from the
> back.
> The most elegant option is not to store indexes, but list iterators, which
> attach to the list element
> and would automatically move, especially if an element is inserted before.
> 
> I could not find such functionality in python lists of [ 1,2,3 ]
> 
> Does python have such functionality ?
> if yes, where can i find it ?

You should be more clear about how to establish the desired insertion 
point.  In your example, you first say that the insertion of B should be 
between 6 and 7. But after A gets inserted, you say that B's insertion 
point should change.  How is anyone able to know what the correct 
insertion point should be at any time?

If the rule is that B should get inserted after a particular known 
element, you can find out the index of that element with list.index() 
and insert just after that. If the rule is "There is an imaginary 
location that starts out after index 6 but moves depending on previous 
insertions", then you will probably need to capture a record of those 
insertions and use it to adjust the invisible insertion point.  But this 
synchronization could be tricky to keep correct depending on what you 
want to do to this list.

So you need to specify clearly what the rules are going to be.
-- 
https://mail.python.org/mailman/listinfo/python-list

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Python list insert iterators

2023-03-03 Thread dn via Python-list

On 03/03/2023 21.22, Guenther Sohler wrote:

Hi Python community,

I have a got an example list like

1,  2,  3, 4, 5, 6, 7, 8, 9, 10
 T   T

and i  eventually want to insert items in the given locations
(A shall go between 2 and 3,  B shall go between 6 and 7)

Right now i just use index numbers to define the place:

A shall insert in position 2
B shall insert in position 6

However when i insert A in position 2, the index for successful insertion
of B gets wrong
(should now be 7 instead of 6)


The danger here is using the index to have meaning beyond its function 
(a position relative to the beginning/end).




No, it's not an option to sort the indexes and start inserting from the
back.


Without explaining this criteria (and any others), suggestions can only 
be guesses!



The most elegant option is not to store indexes, but list iterators, which
attach to the list element
and would automatically move, especially if an element is inserted before.

I could not find such functionality in python lists of [ 1,2,3 ]


So, if list doesn't float-your-boat, what about moving to something else?


Does python have such functionality ?
if yes, where can i find it ?


dict - where the keys indicate relative position

linked-list (https://en.wikipedia.org/wiki/Linked_list) where each value 
is accompanied by a "pointer" which addresses the next value by-index; 
and insertion/deletion is possible by exchanging pointers.

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Python list insert iterators

2023-03-03 Thread Alan Bawden
Guenther Sohler  writes:

   Hi Python community,

   I have a got an example list like

   1, 2, 3, 4, 5, 6, 7, 8, 9, 10
T   T

   and i  eventually want to insert items in the given locations
   (A shall go between 2 and 3,  B shall go between 6 and 7)

   Right now i just use index numbers to define the place:

   A shall insert in position 2
   B shall insert in position 6

   However when i insert A in position 2, the index for successful insertion
   of B gets wrong
   (should now be 7 instead of 6)

   No, it's not an option to sort the indexes and start inserting from the
   back.

If you are definitely inserting from the front, then you can use
negative indexes, since the positions relative to the end of the list
won't be changing.

If you must insert in a random order, that won't help, but you haven't
told us what your real constraints are.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Which more Pythonic - self.__class__ or type(self)?

2023-03-03 Thread Greg Ewing via Python-list

On 4/03/23 7:51 am, avi.e.gr...@gmail.com wrote:


I leave you with the question of the day. Was Voldemort pythonic?


Well, he was fluent in Parseltongue, which is not a good sign.

I hope not, otherwise we'll have to rename Python to "The Language
That Shall Not Be Named" and watch out for horcruxes during code
reviews.

I'll note that he was fluent in Parseltongue, which is not a good
sign.

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list


Re: Which more Pythonic - self.__class__ or type(self)?

2023-03-03 Thread Peter J. Holzer
On 2023-03-03 13:51:11 -0500, avi.e.gr...@gmail.com wrote:
> I do not buy into any concept about something being pythonic or not.
> 
> Python has grown too vast and innovated quite a  bit, but also borrowed from
> others and vice versa.
> 
> There generally is no universally pythonic way nor should there be. Is there
> a C way

Oh, yes. Definitely.

> and then a C++ way and an R way or JavaScript

JavaScript has a quite distinctive style. C++ is a big language (maybe
too big for a single person to grok completely) so there might be
several "dialects". I haven't seen enough R code to form an opinion.

> or does only python a language with a philosophy of what is the
> pythonic way?

No. Even before Python existed there was the adage "a real programmer
can write FORTRAN in any language", indicating that idiomatic usage of a
language is not governed by syntax and library alone, but there is a
cultural element: People writing code in a specific language also read
code by other people in that language, so they start imitating each
other, just like speakers of natural languages imitate each other.
Someone coming from another language will often write code which is
correct but un-idiomatic, and you can often guess which language they
come from (they are "writing FORTRAN in Python"). Also quite similar to
natural languages where you can guess the native language of an L2
speaker by their accent and phrasing.

hp

-- 
   _  | Peter J. Holzer| Story must make more sense than reality.
|_|_) ||
| |   | h...@hjp.at |-- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |   challenge!"


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list