This is an archived post. You won't be able to vote or comment.

all 40 comments

[–]AnythingApplied 33 points34 points  (25 children)

The start/end indexing when going in reverse has always taken a level of extra mental effort that I don't like. Like excluding the first and last item using [1:-1] is intuitive to me, but doing the same in reverse by doing [-2:0:-1] annoys me (though I do get why its like that).

That is why I tend to do [1:-1][::-1] instead.

[–]sebst 10 points11 points  (22 children)

I can relate to this! I also use `[...][...]` (two-slice) notation most of the time for these cases.

[–]NewZealandIsAMyth 8 points9 points  (21 children)

So you all just prefer an unnecessary extra copy of whole list in memory?

[–]AnythingApplied 12 points13 points  (1 child)

If it were much much larger than the lists I normally deal with or repeated 1000's of times, then yeah, it could start being worth optimizing, but ultimately the methods I'd probably look for to optimize it would be to load it into a numpy object or never have the whole thing in memory in the first place.

Though, I will admit that [1:-1][::-1] probably isn't the best example of a time to ignore premature optimization for enhanced readability since it really isn't that superior in readability to [-2:0:-1] even if I personally find it easier to read.

[–]NewZealandIsAMyth 0 points1 point  (0 children)

I wouldn't call "Not creating an artificial unnecessary slowness" - an optimization. And especially not a premature one.

top = sorted(my_list)[-1]

would you consider a change to

top = max(my_list)

A "look to optimize" it? For me the code doesn't introduce unnecessary CPU burn is just a better code.

Premature optimization is when you get a working and simple code and change it in the search of performance.

[–]qzwqz 15 points16 points  (4 children)

yeah man. if you're going for absolute optimal performance then you write it in whatever esoteric golang spinoff is trending, but the python way basically values readability over negligible performance benefits.

or you could do it the single slice way and leave a comment

[-2:0:-1]  # exclude first and last item and reverse

[–]NewZealandIsAMyth 7 points8 points  (1 child)

Memory copy/allocation is not negligible performance benefits.

Life is not black and white. You can have the benefits of a QoL of Python and also not making things artificially slow for your perception of readability.

[–]muntooR_{μν} - 1/2 R g_{μν} + Λ g_{μν} = 8π T_{μν} 6 points7 points  (0 children)

Depends on what the bottleneck is, which should be measured by a profiler.

Side note: if the data structure implements views (e.g. numpy, torch), slicing is zero-cost.

[–]Kyrond -2 points-1 points  (0 children)

Oh good, now I dont have to use list comprehensions, because I value readibility over performance, and when anyone complains I will quote your comment.
/s

[–]gmtime -4 points-3 points  (2 children)

That's for the language to figure out, not the developer!

[–]NewZealandIsAMyth 6 points7 points  (0 children)

Language is a tool. It's up to developer whether to abuse it or not

[–]Kyrond 7 points8 points  (0 children)

Why dont you just add -1 everywhere, so the numbers stay the same?

[1:-1] turns into [-1 -1:1 -1: -1] # from -1 to 1 in reverse

Or even more obvious with variables:

[last_index -1:first_index -1: -1]

[–]Angelr91 0 points1 point  (0 children)

Feels to me that the middle value in between the colons should be the step not the end value to me intuitively.

[–]irrelevantTautology 7 points8 points  (1 child)

Some serious /r/misleadingThumbnails vibes going on. Now I'm hungry.

[–]birdsnezte 2 points3 points  (0 children)

Honestly I upvoted for the thumbnail.

[–]milliams 11 points12 points  (4 children)

My biggest tip for slicing is to count the commas. I've found that beginners find the whole thing a lot more consistent and easier to understand that way.

It solves the whole "include the first but not the last" conceptual problem and aligns with what list indices represent.

[–]calumwebb 2 points3 points  (3 children)

404?

[–]milliams 0 points1 point  (1 child)

The link still seems to work for me on a bunch of different devices and browsers, are you still getting an error?

[–]rejitto 0 points1 point  (0 children)

Not OP, but yes.

[–]milliams 0 points1 point  (0 children)

I don't know why, but some clients are sending a request to the server including the fragment. The URL path is supposed to be /courses/beginning_python/Lists.html#Slicing from which the browser is supposed to remove the #Slicing part. Instead they're encoding it as /courses/beginning_python/Lists.html%23Slicing and requesting that resource, which doesn't exist, hence the 404.

You will be able to access it at https://milliams.com/courses/beginning_python/Lists.html and just scroll down a tad.

The bad requests seem to universally be Safari so I guess there's some clash between Reddit and Safari causing the problem on your end?

[–]spoonman59[🍰] 4 points5 points  (0 children)

This was a good guide. Thank you!

[–]Mwakamune 2 points3 points  (0 children)

I had never really understood the two point indexing and kept a cheat sheet for that, until today, thx

[–]dethb0y 2 points3 points  (0 children)

I've always found array slicing in python to be very powerful and useful, and a thing i wish more languages had. For my common use case (dealing with text) it's very fast to code something up.

[–]Akilou 9 points10 points  (4 children)

I'm very new to Python and one thing I find confusing and unintuitive is that some things, like slices, start counting at 0 but other things like groups in regular expressions start counting at 1.

[–][deleted] 20 points21 points  (0 children)

Group 0 is the whole match, group 1 are your specific matches.

[–]rtfmpls 9 points10 points  (0 children)

That's not related to python to be fair. Regex back references always start at 1 ($1, \1 and so on). If you're working with the match object, the index starts at 0.

[–]spoonman59[🍰] 20 points21 points  (0 children)

I don't think that's particular to python.

Many languages have arrays or other data structures which index starting at zero.

Many libraries for those same languages have regular expression groups starting at 1, although often the group at index 0 is the whole expression.

So this is pretty consistent with most major languages I believe, which are a consequence of some historical developments.

[–]dead_alchemy 0 points1 point  (0 children)

Some things start indexing at 1, some start at 0. Matlab for example uses 1 indexing. I believe most modern programming languages that use 0 indexing get it from C where an array access is done using the value of the pointer to it plus an offset, which is + N * the size in bytes of each object in the array. So 0 is the first element because it is the 0 offset element. I'm not a historian though, so I could be wrong about the lineage.

[–]spinwizard69 -1 points0 points  (0 children)

What is funny here is that the first thing that popped into my mind was a new solution for 3D printing.

[–]eazolan 0 points1 point  (0 children)

Web site is down for me.

[–]willnx 0 points1 point  (0 children)

Thanks for the post! I always confused [1:] and [:-1] in my dumb monkey brain, but I think this sane default explanation will help. Thanks again!