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
Re: Which more Pythonic - self.__class__ or type(self)?
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
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)?
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
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)?
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
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
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
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)?
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)?
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