[python] Reverse with slices! !! (There is also a commentary on slices!)

A memorandum because it was a new discovery for me regarding slicing. Basically, people say: arrow_double_down: [80% skip](#% E3% 81% 8A% E5% BE% 85% E3% 81% A1% E3% 81% 8B% E3% 81% AD% E3% 82 % B9% E3% 83% A9% E3% 82% A4% E3% 82% B9% E3% 81% A7% E3% 83% AA% E3% 83% 90% E3% 83% BC% E3% 82% B9 ): arrow_double_down:

The basics of slicing! !!

I think you may also slice and extract elements when extracting elements from lists or strings. slice? what is that? is it delicious? Let's explain how to use it for those who say.

Postscript (2019/05/27)

In anticipation of the end of support for python2, the notation has been modified to match python3.

Preparation

It's not a slice: sweat_smile:

#A range object is fine, but I dare to convert it to a list object for explanation.
a = list(range(0,10)) 
a[2] #2

Slice normally

#i-th to j-Extract the first element
#(However, 0<= i <Satisfy the relationship of j
#Also, [i<When 0 i= len(a) + i】【j <When 0 j= len(a) +j])
a[i:j] #[a[i], a[i+1], a[i+2], ..., a[j-1]]
#2nd to 7th(8-1)Extract the second element
a[2:8] #[2, 3, 4, 5, 6, 7]
#If i is omitted, from the start point
a[:6] #[0, 1, 2, 3, 4, 5]
#If j is omitted, until the very end of the element
a[7:] #[7, 8, 9]

Slice from behind

If you make it a negative number, it will count from the back.

# [-1]Take out the last element with
#this is[len(a)-1]I think it is synonymous with (not reading the source)
a[-1] #9
# -From 8th-6(-5-1)Extract the second element
a[-8:-5] #[2, 3, 4](donotuse)
#From the starting point-6(-5-1)Extract the second element
a[:-6] #[0, 1, 2, 3](Almostneverused)
# -Extract elements from 8th to end point
a[-2:] #[8, 9](Ioftenuseittotakeoutextensions)

Since the rule of "extracting the j-1st element from the i-th" does not change, the following example is also possible.

#From the second-6(-5-1)Extract the second element
a[2:-5] #[2, 3, 4]
# -8th to 5th(6-1)Extract the second element
a[-8:6] #[2, 3, 4, 5]

PythonWeb is the most easy-to-understand explanation of the concept of slicing.

Take a step and slice! !!

Introducing how to use slices one step further as a premise! Is it surprising to those who do not know? I didn't know from here.

Step slice (named arbitrarily)

Strictly speaking, including this step, it is within the slice specifications in python. So, strictly speaking, it is strange to call it a step slice. However, please forgive me if it is easy to understand. .. ..

#i-th to j-Extract the first element every k
#(However, the constant c is 0<= c < (j-i)/Maximum integer that satisfies k)
a[i:j:k] #[a[i+0*k], a[i+1*k], a[i+2*k], ..., a[i+c*k]]
#Extract every 3 elements from the whole
a[::3] #[0, 3, 6, 9]
#Take out every two elements while cutting out
a[2:8:2] #[2, 4, 6]

If the step value (ʻa [:: k ← this guy] `) is a positive integer, step based on the cut out element (think of it). By the way, ** "0" cannot be specified for the step value ** </ font> (specification).

Of course, step slicing is also possible by omitting the start and end points.

#5 from the starting point(6-1)Extract every two second elements
a[:6:2] #[0, 2, 4]
#Extract every two elements from the 7th to the end point
a[7::2] #[7, 9]

Step slice from behind

If the step value is a negative number, it will be taken out in steps in ** reverse order (← important) **.

#From behind using negative numbers
a[::-3] #[9, 6, 3, 0]

If you want the step value to be a negative integer, I think it's basically better to use it only in this way (the reason will be described later).

Application of step slice

* This section has nothing to do with the main line, so you can skip it. </ font>

If you want to slice the step value to a negative integer, it will be as follows. But it's difficult. Therefore, you may not want to use it for code reviews or because it's hard to see what you're doing when you look back at it later.

#Elements from the 7th to the starting point-Take out every two
a[7::-2] # [7, 5, 3, 1]
#The 5th element from the end point-Take out every two
a[:4:-2] # [9, 7, 5]
#The 8th to 3rd elements-Take out every two
a[8:2:-2] # [8, 6, 4]
# -From the second-Up to 7 elements-Take out every 3
a[-2:-8:-3] # [8, 5]

Actually, only in this case (when the step value is a negative integer), conceptually, it is "extract the ** j + 1 ** th element from the i-th element every k". (If the value of i or j is omitted in all slices, the above rules do not apply.) Also note that unlike other cases, the relationship is ** i> j **.

Recall that ** in reverse order **, which I mentioned earlier as important. If k <0, it seems good to think that the magnitude relationship is reversed for i and j as well. (If you reverse the positive and negative of each part in mathematics, it may be close to the image that the magnitude relationship is reversed.)

Please wait! Reverse with slices! !!

For the time being. It doesn't matter, but if you look at here and use python, you can easily create sentences that read from the opposite side 3 Enter as if you were cooking minutes. (**! The story of Augi Hum Amirep Zekamashi x Tanako ** without anchors in the image)

konata = 'Konata x Shimakaze Premium Figure Anchor!'
print(''.join(reversed(konata)))
#!! Sumashi Anchor Removal Augi Hum Amirep Zekamashi x Tanako

But unfortunately, I don't like this method because it creates an object in the reversed (konata) part once. Be smarter! !! I was looking for various things! !! Familiar, stack overflow Best way to create a “reversed” list in Python?

Those who have read from the top have already noticed. It will be as follows.

print(konata[::-1])
#Metamorphosis notation: print(konata[-1:0 - len(konata):-1])
#!! Sumashi Anchor Removal Augi Hum Amirep Zekamashi x Tanako

Very very very very SMART!! I'm too excited. Moreover, as you can see from the above link, it seems to be fast. (I have not verified) In that respect as well, it's ** SMART **.

Summary

** If you do it in reverse order, make it [list or string] [:: -1]! !! ** **

[Bonus] Slice theorem (?)

For [list or character string] [i: j: k], if the step value k is not specified, it is defined as k = 1 (according to the specifications). Also, [i = len ([list or character string]) + i when i <0] [j = len ( [list or character string]) + j when j <0]. At that time, the following holds.

  1. When k> 0, "from i-th to j-extracts the first element every k (i <j)"
  2. When k <0, "extract every k elements from the ith to j + 1st element (i> j)"

However, it is not established when the value of i or j is omitted.

reference

Chapter 4 Embedded-4.6.1 Common Sequence Operations

Recommended Posts