Page 1 of 1

Python Tips and Tricks - Second Edition (Indexing Lists and Strings)

#1 scalt  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 63
  • View blog
  • Posts: 342
  • Joined: 22-November 07

Posted 31 August 2011 - 02:04 PM

OK so it's been a while since the first edition but I finally have a spare 5 minutes where I can sit down and write another one so here it is :).

Messing With Indices
One of the things that makes Python so awesome is its list indexing system (and the fact that this often applies to other things than lists). I know this has been mentioned elsewhere but I havn't seen a proper tut on it yet so here goes.

IMPORTANT - while everything you see in here uses lists as the example datastructure you can use these exact techniques on strings as well (extract single characters/chunks of strings/reverse strings)

As you are probably aware, lists in Python are indexed using square brackets ('[]'), usually with a number inside them. What you may not be aware of is that you can perform much more jiggery pokery than retrieving a single list element using the square brackets, ie
mylist = [0,1,2,3,4,5,6,7,8,9]

print 'Indices'
print mylist[0]
print mylist[-1]
print mylist[-2]
print ''
print 'Ranges'
print mylist[:]
print mylist[0:2]
print mylist[:2]
print mylist[-2:]
print mylist[5:-1]
print ''
print 'Complex Ranges'
print mylist[::-1]
print mylist[8:3:-2]
print mylist[5:0:-1]
print mylist[5::-1]
print mylist[0:5:2]
print mylist[-3:5:-1]

#OUTPUT:
#>>>
#Indices
#0
#9
#8
#
#Ranges
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
#[0, 1]
#[0, 1]
#[8, 9]
#[5, 6, 7, 8]
#
#Complex Ranges
#[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
#[8, 6, 4]
#[5, 4, 3, 2, 1]
#[5, 4, 3, 2, 1, 0]
#[0, 2, 4]
#[7, 6]
#>>>


Hopefully you can figure out what's going on here fairly easily, try copying the code into a console of your own and have a play with it.

You can 'reverse index' a list by simply whacking a negative number in the brackets, starting with '-1' for the last entry - think of it as 'mylist[len(mylist)-x]' where 'x' is any integer.

To extract a range of values out you specify the index at which you want to start, add a ':', then specify the EXCLUSIVE index at which you want to finish (ie mylist[4:6] will return mylist[4] and mylist[5]). As you can see from the examples the negative indices will work here as well. If you want to start at index '0' or finish at the last element (inclusive) then you can leave that part of the range expression blank, ie '[0:5]' = '[:5]' and '[5:len(mylist)]' = '[5:]'

To extract a slightly more complicated range of values you can use what is effectively a compact 'for' loop in the brackets using the format [a:b:c] where:
- a is the start index
- b is the exclusive end index
- c is the step size
If you want to iterate backwards (ie reverse the list) then use a negative number for 'c'. You will need to update 'a' and 'b' to reflect this as well, obviously if you are iterating backwards then you will start at a higher index and finish at a lower one, as a general rule:

a > b where c > 0
a < b where c < 0

There is a particular trick you will want to remember with this method and it has particular significance when c < 0. If you have a negative 'c' and you want to move down through your list to the beginning you can't set 'b' to 0 ([4:0:-1]) because that will iterate through your list and IGNORE the '0' index (remember 'b' is an EXCLUSIVE bound). The way you get around this is to leave 'b' blank as we discussed with the ranges scenario above, ie [4::-1]. Python will assume that because 'c' < 0, the blank 'b' should refer to the beginning of the array, not the end and everything should work as expected, returning [3,2,1,0].

That's pretty much the end of this tutorial, I'll try and get the next one out soon where I will be showcasing inline-ifs and will introduce some handy hints for File I/O. Feel free to ask questions below.

Is This A Good Question/Topic? 3
  • +

Replies To: Python Tips and Tricks - Second Edition (Indexing Lists and Strings)

#2 fromTheSprawl  Icon User is offline

  • Monomania
  • member icon

Reputation: 513
  • View blog
  • Posts: 2,063
  • Joined: 28-December 10

Posted 31 August 2011 - 05:49 PM

Question! What does this imply?

[::-1] 


It reverses strings, but the first and second values are empty.
You showed that to me on my snippet, ^^
Was This Post Helpful? 0
  • +
  • -

#3 scalt  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 63
  • View blog
  • Posts: 342
  • Joined: 22-November 07

Posted 31 August 2011 - 06:11 PM

[::-1] would imply that a=len(mylist)-1 (the last entry). The Python interpreter will assume you mean the last entry because 'c' is '-1' so setting 'a' to the first entry would be meaningless (you get an empty list back). Given that 'a' is assumed to be the last entry, Python will assume that 'b' must refer to the INCLUSIVE first entry. Remember that 'b' is usually an EXCLUSIVE bound, the only way to reference the first entry is to leave it blank. 'c' is really what drives all the assumptions here, if you use '1' instead of '-1' then a=0 and b=len(mylist) and you will just get your original list back.

It is worth noting here that if you put nonsense numbers in for 'a', 'b' or 'c' you won't get an error! Provided they are legit integer values (or call functions that return integer values) Python will bound all your parameters so they don't cause exceptions. This means that if you have a list of length 4 and you use [1:10:1] it will bound the '10' to '5' (remember 'b' is EXCLUSIVE). If you give it complete jargon you will just get an empty list back, ie a list of length 4 with [8:10:1]' you will get a blank list, ie:
x = [1,2,3,4]
print x
print x[8:10:1]
print x[1:10:1]
print x[12::-2]
print x[::-102]

#OUTPUT:
#>>>
#[1, 2, 3, 4]
#[]
#[2, 3, 4]
#[4, 2]
#[4]
#>>>

#Example with string:
x = 'some string'
print x
print x[::-1]
print 'some other string'[100::-2]
#OUTPUT:
#>>>
#some string
#gnirts emos
#git et ms
#>>> 


This post has been edited by scalt: 31 August 2011 - 06:12 PM

Was This Post Helpful? 0
  • +
  • -

#4 fromTheSprawl  Icon User is offline

  • Monomania
  • member icon

Reputation: 513
  • View blog
  • Posts: 2,063
  • Joined: 28-December 10

Posted 31 August 2011 - 06:23 PM

Oh, so this means:

[a=len(word):b=len(word):c=-1]
'apple'.[::-1]
=
[4:4:-1]

'elppa'


Step backwards one at a time using c(-1), the range is b(4), and it starts with the index a(4).

That sounds about right?

^^
Was This Post Helpful? 0
  • +
  • -

#5 scalt  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 63
  • View blog
  • Posts: 342
  • Joined: 22-November 07

Posted 31 August 2011 - 06:41 PM

Almost ;)

'b' isn't a range, it's a bound (the index at which Python will stop building you sub-list). Because the bound is exclusive, that means Python won't return the value at that index, just everything leading up to it. That means that TECHNICALLY speaking, 'apple'[::-1] is actually 'apple'[4:-1:-1]. HOWEVER using -1 for 'b' has other implications because we use negative integers for indexing the end of lists. We get around this by leaving 'b' blank and trusting Python to sort it out.

If you still don't understand, have a bit more of a play in your Python console swapping some different values out for 'a', 'b' and 'c' then come back if you're still stuck.
Was This Post Helpful? 0
  • +
  • -

#6 fromTheSprawl  Icon User is offline

  • Monomania
  • member icon

Reputation: 513
  • View blog
  • Posts: 2,063
  • Joined: 28-December 10

Posted 31 August 2011 - 06:57 PM

STUUCK!

Lol I kid.

Yeah that was what I meant, sorry I used 'range'. But what I didn't know is it won't build the last index, thanks for that! So it means that it would b would depend on c, not a?
Was This Post Helpful? 0
  • +
  • -

#7 scalt  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 63
  • View blog
  • Posts: 342
  • Joined: 22-November 07

Posted 31 August 2011 - 07:26 PM

Yep that's correct :)
Was This Post Helpful? 0
  • +
  • -

#8 fromTheSprawl  Icon User is offline

  • Monomania
  • member icon

Reputation: 513
  • View blog
  • Posts: 2,063
  • Joined: 28-December 10

Posted 31 August 2011 - 07:34 PM

Now I get it, thanks dude! Hope to see more of your tutorials! ^^
Was This Post Helpful? 0
  • +
  • -

#9 scalt  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 63
  • View blog
  • Posts: 342
  • Joined: 22-November 07

Posted 31 August 2011 - 07:36 PM

No problem, glad I could help :)
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1