Slices and More

Wed 07 October 2015

Filed under Python

Slices

First: What is 'Slicing'? Slicing allows you to get a substring from a string. Or a portion of a list. That 'slice' is returned.

The syntax: sequence[start:end:step].
Or you can also think of it as sequence[from index: until index (not including): step]. Remember, Python uses a 0 index. See the docs

Direction

  • If the 'start' is absent or a positive number, then the 'start' is from the left; in other words - forward. If the 'start' is a negative number, then the 'start' index begins from the end.

  • If the 'end' is absent or a positive number, then the 'end' is from the left; in other words - forward. If the 'end' is a negative number, then the 'end' index begins from the end.

  • If the 'step' is absent or a positive number, then the 'start' is from the left; in other words - forward. If the 'step' is a negative number, then the 'start' is from the right, from the end; in other words - backward. (see examples below)

Defaults

  • If there is no 'start', then it begins from the beginning - depending on the direction.

  • If there is no 'end', then it goes until the end - depending on the direction.

  • If there is no 'step', then it goes one by one forward. If there is a 'step', then it counts that number, depending on the direction.


Some examples, using a string. And a list:

mystr = "ABCD"
mylist = ["a", "b", "c", "d"]
the code result explanation
mystr[0]
'A'
only the element in index 0
mylist[0]
'a'
only the element in index 0
mystr[1:]
'BCD'
start from index 1 until the end
mylist[1:]
['b', 'c', 'd']
start from index 1 until the end
mystr[:1]
'A'
start from index 0 until index 1
mylist[:1]
['a']
start from index 0 until index 1
mystr[1:3]
'B','C'
start from index 1 until index 3
mylist[1:3]
['b', 'c']
start from index 1 until index 3
mystr[1:6]
'B','C','D'
start from index 1 until index 6 (or until the highest index in the sequence)
mylist[1:6]
['b', 'c', 'd']
start from index 1 until index 6 (or until the highest index in the sequence)
mystr[1::2]
'B','D'
start from index 1 until index 6 (or until the highest index in the sequence), in step 2
mylist[1::2]
['b', 'd']
start from index 1 until index 6 (or until the highest index in the sequence), in step 2
mystr[-1]
'D'
start at the end, for 1 index (In other words, the last element)
mylist[-1]
['d']
start at the end, for 1 index (In other words, the last element)
mystr[:-1]
'ABC'
start at index 0, until 1 index starting from the end
mylist[:-1]
['a', 'b', 'c']
start at index 0, until 1 index starting from the end
mystr[2:2]
''
start at index 2, until index 2. (In other words, nothing - an empty string)
mylist[2:2]
[]
start at index 2, until index 2. (In other words, nothing - an empty list)
mystr[2:1]
''
start at index 2, until index 1. (Which cannot happen. In other words, nothing - an empty string)
mylist[2:1]
[]
start at index 2, until index 1. (Which cannot happen. In other words, nothing - an empty list)
mystr[-3:-1]
'BC'
start at 3rd to last index, until the 1st to last index
mylist[-3-1]
['b','c']
start at 3rd to last index, until the 1st to last index
mystr[::-1]
'DCBA'
start from the end - going backwards, until the beginning (In other words reversed).
mylist[::-1]
['d', 'c', 'b', 'a']
start from the end - going backwards, until the beginning (In other words reversed).
mystr[:]
'ABCD'
start from the beginning, until the end (In other words, a copy)
mylist[:]
['a', 'b', 'c', 'd']
start from the beginning, until the end (In other words, a copy)
mystr[2::-1]
'CBA'
start from the end - going backward, 2 indexes in, until the beginning
mylist[2::-1]
['c', 'b', 'a']
start from the end - going backward, 2 indexes in, until the beginning
mystr[2:1:-1]
'C'
start from the end - going backward, 2 indexes in, for 1 index
mylist[2:1:-1]
['c']
start from the end - going backward, 2 indexes in, for 1 index
del mystr[:]
'str' object does not support item deletion
del mylist[:]
[]
deletes the contents in the list, but not the actual list itself

A few more cool things with Slice

Sometimes, you might find it useful to separate the actual forming of the slice and the passing that slice definition to the actual sequence or list. You can do that with the built-in method slice. The syntax is a = slice(start, end, step) and then you can use it with the string or list - as mylist[a].

>>>a = slice(1, 5, 2)
>>>mylist[a] 
['b', 'd'] # start at index one, end at index 5, with step 2

>>>mystr[a]
'BD'

>>>a.start
1
>>>a.stop
5
>>>a.step
2

Conditional Start/ Stop/ Step You can use inline conditional statements* directly in the slice definition - for the 'start', 'stop' or 'step'. Note you can use None if you don't want to include the 'start', 'stop' or 'step'.

*Inline conditional statements are one-liner if statements. [See more] (http://www.deekras.com/if-else.html)

>>>i=True
>>>mylist[1 if i else 2]
'b'
>>>mylist[0: 2 if i else 3]
['a', 'b']
>>>mylist[::-1 if i else 1]
['d', 'c', 'b', 'a']


>>>i=2
>>>mystr[3: None if i <0 else i: -1]
'D'

Assignment

You can assign specified index with a new value. It deletes the elements in those indexes and inserts new values. - If no new values are provided, it just deletes the elements in those indexes.

  • If there are more elements to be assigned than those that are deleted, then those 'extra' elements are inserted right after those that did have a place to be inserted.

It actually changes the list; and does not return anything. (You'll have to call the list to see the actual change.) Note: Assignment does not work with strings.

the code result explanation
mylist[0] = "1"
['1', 'b', 'c', 'd']
assigns "1" in the 0 index
mylist[0] = "1", "2"
[('1', '2'), 'b', 'c', 'd']
assigns all into the 0 index
mylist[0:2] = "1"
['1', 'c', 'd']
is prepared to assign into the 0 index and the 1 index, so deletes those 2 elements. but only has 1 element to assign
mylist[0:2] = "1", "2"
['1', '2', 'c', 'd']
is prepared to assign into the 0 index and the 1 index, so deletes those 2 elements. and assigns the "1" and "2" to those indexes
mylist[0:1] = "12"
['1', '2', 'b', 'c', 'd']
is prepared to assign to the 0 index. it reads the string "12" as iterator, so places each element - the "1" and "2" in the iterator into the list - starting at the 0 index.
mylist[0:1] = "12",
['12', 'b', 'c', 'd']
is prepared to assign to the 0 index. it reads the string as an item in a tuple - notice the comma at the end. so places the "12" into the list - starting at the 0 index.
mylist[1:2] = []
['a', 'c', 'd']
is prepared to assign to the 1 index. There is nothing to assign, so essentially, it deletes that element.
mylist[:] = "1", "2", "3"
['1', '2', '3']
is prepared to assign to the entire list. And places the elements into the list - starting at the beginning
mylist[0:2] = ["1"]
['1', 'c', 'd']
mylist[0:2] = ["1","2", "3"]
['1', '2', '3', 'c', 'd']
mystr[0] = "1"
TypeError: 'str' object does not support item assignment

islice

islice is from the itertools library. It creates an iterator from the slice. This saves memory since the data is not produced from the iterator until it is needed. See the docs

>>>from itertools import islice, count

>>>islice(mylist, 0, 2)
<itertools.islice object at 0x7f00bf0937e0>

>>>list(islice(mylist, 0, 2))
['a', 'b']

>>>islice(mystr, 0, 2)
<itertools.islice object at 0x7f00bf0937e0>

>>>list(islice(mystr, 0, 2))
['A', 'B']

>>>for i in islice(count(), 0, 100, 10):
      print i,
0 10 20 30 40 50 60 70 80 90

Comments


DeeKras.com © Dee Kras Powered by Pelican and Twitter Bootstrap. Icons by Font Awesome and Font Awesome More