Programmer's Python Data - Sequences
Written by Mike James
Monday, 11 December 2023
Article Index
Programmer's Python Data - Sequences
Slices
Modifying Sequences
Page 1 of 3

Python takes a unique and very logical approach to basic data structures. As the next step up from numbers it has the sequence. Find out how it all works in this extract from Programmer's Python: Everything is Data.

Programmer's Python
Everything is Data

Is now available as a print book: Amazon

pythondata360Contents

  1. Python – A Lightning Tour
  2. The Basic Data Type – Numbers
    Extract: Bignum
  3. Truthy & Falsey
  4. Dates & Times
    Extract Naive Dates
  5. Sequences, Lists & Tuples
    Extract Sequences
  6. Strings
    Extract Unicode Strings
  7. Regular Expressions
    Extract Simple Regular Expressions
  8. The Dictionary
    Extract The Dictionary
  9. Iterables, Sets & Generators
    Extract Iterables
  10. Comprehensions
    Extract Comprehensions
  11. Data Structures & Collections
    Extract Stacks, Queues and Deques
    Extract Named Tuples and Counters
  12. Bits & Bit Manipulation
    Extract Bits and BigNum
    Extract Bit Masks ***NEW!!!
  13. Bytes
    Extract Bytes And Strings
    Extract Byte Manipulation
  14. Binary Files
    Extract Files and Paths
  15. Text Files
    Extract Text Files & CSV
  16. Creating Custom Data Classes
    Extract A Custom Data Class
  17. Python and Native Code
    Extract Native Code
    Appendix I Python in Visual Studio Code
    Appendix II C Programming Using Visual Studio Code

<ASIN:1871962765>

<ASIN:1871962749>

<ASIN:1871962595>

<ASIN:B0CK71TQ17>

<ASIN:187196265X>

This concept includes ideas that other languages divide up into different types of data – arrays, lists and strings. In Python there are sequences of different types that cross the usual divisions. In this chapter we cover lists, tuples and the range object. Other built-in sequences are strings, which are covered in the next chapter and bytes, bytearray and memoryview which are covered in Chapter 12.

What Is A Sequence?

A sequence is just a set of things indexed by the whole numbers starting counting from zero. Python has many implementation of sequences and you can create your own, but the archetypal sequence is the list and this is used in all the examples in this chapter, but notice the ideas are general. That is, a sequence is best thought of as a set of "mixin" methods that are present in a range of different objects.

Typically a particular element of a sequence is picked out using an index. S[i] is the ith element of S and it is usually allowed to be any Python object including another sequence. This use of square brackets is generally called index notation or indexing. S[0] is the first element of the sequence S and S[n-1] is the last element if it has a total of n elements. The built-in function len(S) returns the length of the sequence.

In general the elements of a sequence are references to objects and this can cause confusion if you are not expecting "reference" semantics. For example:

S = [MyObject,0,MyObject]

creates a sequence with S[0] and S[2] both referencing the same object. This means that any changes made to the object referenced by S[0] is made to the same object as referenced by S[2]. For example:

S[0].myAttribute = 42
print(S[2].myAttribute)

displays 42 assuming MyObject has a myAttribute attribute. In general, assignment to a sequence does not create a new copy of the object being assigned.

Lists

Elements are stored in sequences using assignment. Exactly how this is done depends on the type of sequence, but essentially it involves the use of a sequence literal. For example, a list literal is created by writing the elements between square brackets:

S = [a,b,c]

creates a list with elements S[0], S[1] and S[2] set to reference a, b and c respectively. Notice a, b and c are any Python objects you care to specify. Also notice that a special case is [] which creates an empty list.

You can also use the list constructor to convert any iterable into a list. An iterable is another mixin-like sequence that doesn’t support indexing but does support being iterated through from start to finish. For example, a tuple, see later, is a sequence but all sequences are iterables so you can convert a tuple to a list using:

list((1,2,3))

returns [1,2,3].

A more advanced way of creating a sequence is to use an "iterable" as part of a list comprehension or within the list constructor, see Chapter 9 which takes an in-depth look at iterables.

There are two basic operators, + and *, that work with sequences. The + operation "adds" two sequences together, that is:

S = S1+S2

creates a new sequence S with the elements of S1 followed by the elements of S2. The * operator repeats a sequence:

S = S1*3

creates a new sequence S with the elements of S1 repeated three times. It is equivalent to:

S = S1+S1+S1

There are also some standard methods that apply to all sequences:

 x in S

True if an item of S is equal to x, otherwise False

 x not in S

not(s in S)

 len(S)

length of S

 min(S)

smallest item of S

 max(s)

largest item of S

 S.index(x,i,j)

index of the first occurrence of x in S at or after index i and before index j. You can omit i or j.

 S.count(x)

total number of occurrences of x in S

Most of these are useful ways of avoiding having to write an explicit for loop and they are generally faster.

Sequences come in two forms, just like most other data structures, mutable and immutable. A mutable sequence is one in which you can change elements after it has been created. Obviously, an immutable sequence is one that cannot be changed. Python generally provides both mutable and non-mutable versions of sequences, but not always. For example, a list is mutable but a tuple is an immutable list. That is, after you have created a list you can change any element. For example:

S = [1,2,3]
S[0] = 42

produces the list [42,2,3]. If you try the same thing with a tuple you will generate an exception, more on tuples later.

You can also use negative indices and this are taken to refer to elements from the end of the sequence. That is S[-1] is the last element of the sequence. The way that this works is that if you use a negative index S[-i] this is converted to S[len(S)-i]. For example, with:

S = [1,2,3]
print(S[-1])
print(S[len(S)-1])
print(S[2])

all of the print instructions display 3, the final value.

Any attempt to access an element which doesn’t exist results in an exception. For example:

S = [1,2,3]
print(S[4])

generates an exception. Similarly negative values can result in an exception. For example:

S = [1,2,3]
print(S[-4])

which tries to access S[-1] which doesn’t exist as S[0] is the first element and notice that in this case the index isn’t modified – the adjustment to negative indices is applied only once.

The fact that you cannot reference non-existent elements also means that for mutable sequences you can’t create new elements by assignment. That is:

S = [1,2,3]
S[4] = 42

also generates an exception because S[4] doesn’t exist and assignment doesn’t create a new element, only changes existing elements. You can extend a sequence with new elements, but it is easier to understand how after we look at slices.


Prev - Next >>

Last Updated ( Monday, 11 December 2023 )