|
 |
CS 3723
Programming Languages |
3.1 Strings
|
|
Reference links given below will be to the online book:
Building skills in Python
3.1. Strings:
See especially
Strings for a lot of material not covered below.
3.1.1. Extended Slices:
See
Extended Slices.
These apply equally to strings, tuples, and lists. But keep in
mind that strings and tuples are immutable, so copies must be made
in those cases.
- slice operator [ ] with a single
operand: this picks off the element indexed by the operand.
A sequence a (string, tuple, or list) has its elements
counted by either one of:
0, 1, ..., len(a)-2, len(a)-1
-len(a), -len(a)+1, ..., -2, -1
Any index i satisfying i > len(a)-1. or i < -len(a)
will raise an IndexError exception.
slice operator with a two operands:
this looks like [start:end], and picks off
a contiguous string of elements from start up to but not
including end. Of course these have to be in range, they
can be variables, start defaults to 0 and end defaults to
len(a). The program below shows a few simple cases of this.
slice operator with a three operands:
this looks like [start:end:step] ("step" is also called "stride").
step defaults to 1 and cannot be 0, but can be negative.
Here, the construct steps through the sequence forward (positive step)
or backward (negative step), picking off elements.
Again some examples are given below.
By far the most important
example is to use the operator [::-1] to reverse a sequence (string,
list, or tuple).
(There doesn't seem to be a reverse() method for strings, though
there is one for lists.)
Use of Extended
Slices |
Source |
Output |
# slice.py: extended slices
import sys
a = "abcdefghij"
sys.stdout.write("a= " + a + '\n')
sys.stdout.write("a[1:5]= " + a[1:5] + '\n')
sys.stdout.write("a[3:]= " + a[3:] + '\n')
sys.stdout.write("a[:4]= " + a[:4] + '\n')
sys.stdout.write("a[-5:-2]=" + a[-5:-2] + '\n')
sys.stdout.write("a[-5:7]= " + a[-5:7] + '\n')
sys.stdout.write("a[-5:2]= " + a[-5:2] + '(empty)\n')
abc = "abcdefghijklmnopqrstuvwxyz"
sys.stdout.write("abc= " + abc + '\n')
sys.stdout.write("abc[::2]= " + abc[::2] + '\n')
sys.stdout.write("abc[1::2]= " + abc[1::2] + '\n')
sys.stdout.write("abc[::-1]= " + abc[::-1] + '\n')
sys.stdout.write("abc[-1::-2]=" + abc[-1::-2] + '\n')
sys.stdout.write("abc[:-8:3]= " + abc[:-8:3] + '\n')
| % python slice0.py
a= abcdefghij
a[1:5]= bcde
a[3:]= defghij
a[:4]= abcd
a[-5:-2]=fgh
a[-5:7]= fg
a[-5:2]= (empty)
abc= abcdefghijklmnopqrstuvwxyz
abc[::2]= acegikmoqsuwy
abc[1::2]= bdfhjlnprtvxz
abc[::-1]= zyxwvutsrqponmlkjihgfedcba
abc[-1::-2]=zxvtrpnljhfdb
abc[:-8:3]= adgjmp
|
3.1.2. Exchanging Rows and Columns
(transpose):
I was playing around with extended slices, trying a succession of
incremented slices, and hit on the idea of arranging a list of
names by column as is done by default in Linux/Unix using the ls
utility to output file names in a directory. Looked at another way,
this does a sort of matrix transpose, except that the number of
columns depends on how long the individual file names are and how
wide the available field is.
It's interesting that the Python function works with any
sequence -- I show it for three cases: strings, lists of integers, and
lists of strings. (For strings, it's invoking str() on
something already a string, but that does nothing.)
Use of Extended
Slices |
Source |
Output |
# exch.py: extended slices
import sys
def exch(a, n):
sys.stdout.write("exch(.," +
str(n)+'):\n')
m = [None] * n
for j in range(0,n):
m[j] = a[j::n]
for j in range(0,n):
sys.stdout.write(str(m[j])+'\n')
sys.stdout.write('\n')
# sys.stdout.write(str(m) + '\n')
a = "abcdefghijklmnopqrstuvwxyz"
# sys.stdout.write("a= " + a + '\n')
exch(a,3)
exch(a,4)
exch(a,5)
exch(a,7)
b = []
for i in range(0,22):
b.append(i)
# sys.stdout.write(str(b) + '\n\n')
exch(b,3)
exch(b,4)
exch(b,5)
exch(b,7)
| % python exch.py
exch(.,3):
adgjmpsvy
behknqtwz
cfilorux
exch(.,4):
aeimquy
bfjnrvz
cgkosw
dhlptx
exch(.,5):
afkpuz
bglqv
chmrw
dinsx
ejoty
exch(.,7):
ahov
bipw
cjqx
dkry
elsz
fmt
gnu
|
(a few blanks inserted below)
exch(.,3):
[0, 3, 6, 9, 12, 15, 18, 21]
[1, 4, 7, 10, 13, 16, 19]
[2, 5, 8, 11, 14, 17, 20]
exch(.,4):
[0, 4, 8, 12, 16, 20]
[1, 5, 9, 13, 17, 21]
[2, 6, 10, 14, 18]
[3, 7, 11, 15, 19]
exch(.,5):
[0, 5, 10, 15, 20]
[1, 6, 11, 16, 21]
[2, 7, 12, 17]
[3, 8, 13, 18]
[4, 9, 14, 19]
exch(.,7):
[0, 7, 14, 21]
[1, 8, 15]
[2, 9, 16]
[3, 10, 17]
[4, 11, 18]
[5, 12, 19]
[6, 13, 20]
|
Result of printing m in each case:
['adgjmpsvy', 'behknqtwz', 'cfilorux']
['aeimquy', 'bfjnrvz', 'cgkosw', 'dhlptx']
['afkpuz', 'bglqv', 'chmrw', 'dinsx', 'ejoty']
['ahov', 'bipw', 'cjqx', 'dkry', 'elsz', 'fmt', 'gnu']
[[0, 3, 6, 9, 12, 15, 18, 21], [1, 4, 7, 10, 13, 16, 19], [2, 5, 8, 11, 14, 17, 20]]
[[0, 4, 8, 12, 16, 20], [1, 5, 9, 13, 17, 21], [2, 6, 10, 14, 18], [3, 7, 11, 15, 19]]
[[0, 5, 10, 15, 20], [1, 6, 11, 16, 21], [2, 7, 12, 17], [3, 8, 13, 18], [4, 9, 14, 19]]
[[0, 7, 14, 21], [1, 8, 15], [2, 9, 16], [3, 10, 17], [4, 11, 18], [5, 12, 19], [6, 13, 20]]
|
Here is the program invoked for a list of file names.
In the output I inserted blanks by hand to make it look more like it
normally would be, but that would be an additional requirement.
This program is just an illustration of the use of extended slices, and
is not how one would want to program it in practice.
|