Σημειωματάριο διάλεξης Πέμπτης 15 Οκτ. 2015

Strings (κείμενα)

Οι μεταβλητές τύπου κείμενο παίρνουν τη τιμή τους με προσδιορισμό του κειμένου εντός διπλών εισαγωγικών (τα οποία εισαγωγικά δεν αποτελούν μέλος της τιμής της μεταβλητής, αλλά χρησιμεύουν μόνο για να προσδιορίσουν την αρχή και το τέλος του κειμένου.

In [1]:
x = "abc"
print x
abc

Αντί για διπλά εισαγωγικά μπορούμε να χρησιμοποιήσουμε και απλά εισαγωγικά. Πάντα κλείνουμε το κείμενο με το ίδιο είδος εισαγωγικών με αυτό που ξεκινήσαμε. Το να γράψουμε "abc' είναι λάθος.

In [1]:
x = 'abc'
print x
abc

Η πράξη + ανάμεσα σε δύο strings υπολογίζει τη συγκόλλησή τους (concatenation). Η τιμή της συγκόλλησης είναι το πρώτο string ακολουθούμενο από το δεύτερο.

In [2]:
x = 'abc'
y = "def"
z = x+y
print z
abcdef

Αν θέλουμε να περιγράψουμε ένα εισαγωγικό ως κομμάτι του string ένας τρόπος είναι να το εσωκλείσουμε στο άλλο είδος εισαγωγικού.

In [3]:
x = 'abc'
print '"'+x+'"'
"abc"

In [3]:
x = 'abc'
print "'"+x+"'"
'abc'

Ένας άλλος τρόπος είναι να γράψουμε το χαρακτήρα \ (backslash) πριν το εισαγωγικό. Ο χαρακτήρας αυτός έχει το νόημα ότι αναιρεί την ειδική λειτουργία του χαρακτήρα που ακολουθεί και τον κάνει να ερμηνεύεται ως ένα απλό γράμμα. Αν ο χαρακτήρας που ακολουθεί το backslash δεν έχει κάποια ειδική ιδιότητα τότε συχνά ο χαρακτήρας backslash προσδίδει κάποια ιδιότητα στο γράμμα που ακολουθεί. Π.χ. με \n παίρνουμε το χαρακτήρα αλλαγής γραμμής (newline) που όταν τυπωθεί έχει ως αποτέλεσμα το τερματικό μας να αλλάξει γραμμή.

In []:
x = 'abc'
print "\""+x+"\""

Τα strings έχουν μήκος (το πλήθος των χαρακτήρων τους) που το υπολογίζουμε με τη συνάρτηση len().

In [4]:
x = "abc def"
print len(x)
7

Ο πρώτος χαρακτήρας ενός string x είναι ο x[0] ενώ ο τελευταίος είναι ο x[l-1], όπου l είναι το μήκος του string.

In []:
x = "abcdefghij0123456789"
print len(x)
print x[0]
print x[19]

Ένα slice (φέτα) ενός string αποτελεί ένα κομμάτι του το προσδιορίζεται από την αρχή και το τέλος του και, ενδεχομένως, και από το βήμα με το οποίο προχωράμε για να επιλέξουμε τους χαρακτήρες του κομματιού. Το slice a:b περιγράφει το κομμάτι του string από τον χαρακτήρα με δείκτη a έως το χαρακτήρα με δείκτη b-1.

In [8]:
x = "abcdefghij0123456789"
print x[3:6]
def
cdefghij0123456789
abcd
adgj

Αν σε ένα slice παραλείπεται το ένα μέρος του τότε υποννοείται ότι το μέρος που παραλείφθηκε έχει την ακραία τιμή του. Έτσι το slice a: περιγράφει το string από το χαρακτήρα με δείκτη a και πέρα, ενώ το slice :b περιγράφει το string μέχρι και τον b-1 χαρακτήρα.

Το slice μπορεί και να έχει και ένα τρίτο προσδιορισμό a:b:c οπότε οι δείκτες τους οποίους προσδιορίζει είναι αυτοί που αρχίζουν από a, προσωράνε με βήμα c, όσο είναι μικρότεροι (αυστηρά) του b.

In [11]:
x = "abcdefghij0123456789"
print x[10:]
print x[:10]
print x[10:20:3]
0123456789
abcdefghij
0369

Μορφοποιημένη εκτύπωση (formatted printing)

Πολλές φορές θέλουμε να τυπώσουμε ένα string μέρος του οποίου καθορίζεται από μια μεταβλητή. Για παράδειγμα, στο επόμενο πρόγραμμα θέλουμε να τυπώσουμε στο τέλος ένα κείμενο που μας λέει ποιος είναι ο μικρότερος (από τους δύο αριθμούς που δώσαμε), ποιος είναι ο μεγαλύτερος και ποιο είναι το άθροισμά τους.

Το string που δίδεται στο print περιέχει τα σύμβολα %f τα οποία σημαίνουν ότι σε αυτή τη θέση θα μπει ένα float και το ποιο float θα μπει καθορίζεται από τις τιμές που ακολουθούν μετά το σύμβολο % δεξιά του string.

In [12]:
x = float( raw_input( "Give a real number: "))
y = float( raw_input( "Give a real number: "))

if x > y:
    x, y = y, x

print "The smallest is %f and the largest is %f and their sum is %f" % (x, y, x+y)
Give a real number: 3.1
Give a real number: 4.56
The smallest is 3.100000 and the largest is 4.560000 and their sum is 7.660000

Αν θέλουμε μπορούμε να περιορίσουμε τα ψηφία μετά την υποδιαστολή που τυπώνουμε δίνοντας π.χ. %.3f για τρία ψηφία.

In [13]:
x = float( raw_input( "Give a real number: "))
y = float( raw_input( "Give a real number: "))

if x > y:
    x, y = y, x

print "The smallest is %.3f and the largest is %.3f and their sum is %.3f" % (x, y, x+y)
Give a real number: 3.1
Give a real number: 4.56
The smallest is 3.100 and the largest is 4.560 and their sum is 7.660

Το ίδιο πρόγραμμα γραμμένο για ακεραίους. Για ακεραίους χρησιμοποιούμε %d αντί για %f.

In [28]:
x = int( raw_input( "Give a real number: "))
y = int( raw_input( "Give a real number: "))

if x > y:
    x, y = y, x

print "The smallest is %d and the largest is %d and their sum is %d" % (x, y, x+y)
Give a real number: 3
Give a real number: 2
The smallest is 2 and the largest is 3 and their sum is 5

Για strings χρησιμοποιούμε %s.

In [14]:
first = raw_input("What is your first name? ")
last = raw_input("Your last name? ")

print "Hello %s %s" % (first, last)
What is your first name? Albert
Your last name? Einstein
Hello Albert Einstein

Αν μέσα στο string θέλουμε να δώσουμε το χαρακτήρα % χωρίς αυτός να έχει την ειδική έννοια που μόλις είδαμε τότε τον γράφουμε δύο φορές.

In [15]:
x = float( raw_input( "Give a real number: "))
y = float( raw_input( "Give a real number: "))

if x > y:
    x, y = y, x

percentage = x/y*100

print "The smallest is %f, the largest is %f, and the smal\blest is %.2f%% of the largest" % (x, y, percentage)
Give a real number: 23
Give a real number: 345
The smallest is 23.000000, the largest is 345.000000, and the smallest is 6.67% of the largest

Μέσα σε ένα string o χαρακτήρας \n είναι ο ειδικός χαρακτήρας αλλαγής γραμμής.

In [16]:
x = float( raw_input( "Give a real number: "))
y = float( raw_input( "Give a real number: "))

if x > y:
    x, y = y, x

print "The smallest is %f and the largest is %f\n and their sum is %f" % (x, y, x+y)
Give a real number: 23
Give a real number: 345
The smallest is 23.000000 and the largest is 345.000000
 and their sum is 368.000000

Μπορούμε να ρωτήσουμε αν ένα γράμμα ανήκει σε ένα string με τον τελεστή in.

In [17]:
if "b" in "Bcde":
    print "Yes, it is in"
else:
    print "No, not in"
    
if "c" in "Bcde":
    print "Yes, it is in"
else:
    print "No, not in"
No, not in
Yes, it is in

Υπάρχουν πολλές έτοιμες συναρτήσεις και "μέθοδοι" στην python οι οποίες μεταχειρίζονται strings. Ένα παράδειγμα βλέπουμε παρακάτω με τη μέθοδο replace, η οποία παίρνει δύο ορίσματα τύπου string και επιστρέφει το string από το οποίο καλούμε τη μέθοδο όπου το πρώτο όρισμα έχει αντικατασταθεί από το δεύτερο.

In [18]:
x = "abcdefgab"
y =  x.replace("ab","AB")
print x
print y
abcdefgab
ABcdefgAB

Λίστες

Μια λίστα στην python είναι μια διατεταγμένη ακολουθία από αντικείμενα. Τα αντικείμενα της λίστας αριθμούνται από το 0.

In [19]:
l = [1, 2, 5, 6]
print len(l)
4

In [21]:
l = [1, 2, 5, 6]
print l[0], l[3]
 1 6

In [22]:
l = [1, 2, 5, 6]
print l[4]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-22-6b0aca083c06> in <module>()
      1 l = [1, 2, 5, 6]
----> 2 print l[4]

IndexError: list index out of range

Τα slices δουλεύουν επίσης στις λίστες.

In [25]:
l = ['a', 'ab', 'abc', 'abcd']
print l[1:]
print l[:2]
print l[1:3]
['ab', 'abc', 'abcd']
['a', 'ab']
['ab', 'abc']

Όπως και η συγκόλληση με το σύμβολο +.

In [26]:
l1 = [1, 2, 3]
l2 = [4, 5, 6]
l = l1 + l2
print l
[1, 2, 3, 4, 5, 6]

Σε αντίθεση με τα strings τα στοιχεία μιας λίστας μπορούν να αντικατασταθούν με άλλες τιμές, ακόμη και με τιμές διαφορετικού τύπου.

In [29]:
l = [1, 2, 3, 4, 5, 6]
l[0] = "10"
print l
['10', 2, 3, 4, 5, 6]

Οι λίστες είναι αυτό που ονομάζουμε στην python mutable type. Το να αναθέσουμε σε μια μεταβλητή ως τιμή μια λίστα, όπως φαίνεται παρακάτω στην εντολή x = [1, 2, 3], αυτό που κάνει είναι ότι κάνει τη μεταβλητή αυτή να δείχνει σε εκείνη τη θέση μνήμης όπου είναι αποθηκευμένη η λίστα. Η επόμενη εντολή y = x κάνει το όνομα y να δείχνει στην ίδια θέση μνήμης που δείχνει το όνομα (μεταβλητή) x.

Έτσι η εντολή x[0] = 10 που αλλάζει το πρώτο στοιχείο της λίστας σε 10 πάει και αλλάζει την πρώτη θέση μνήμης, αλλαγή που αντανακλάται και στο x και στο y, όπως φαίνεται από την εκτύπωση.

In [54]:
x = [1, 2, 3]

y = x

x[0] = 10

print x
print y
[10, 2, 3]
[10, 2, 3]

Σε αντίθεση με τις λίστες οι αριθμοί και τα strings είναι immutable types. Όταν τους αναθέτουμε μια τιμή αυτή η τιμή αποθηκεύεται εκεί που είναι και το όνομά τους. Στο παρακάτω πρόγραμμα η x παίρνει την τιμή 1, έπειτα η y παίρνει την τιμή που έχει η x (πάλι 1) αλλά τώρα η διαφορά με πριν είναι ότι η τιμή αυτή αντιγράφεται στη θέση y. Έτσι η μετέπειτα αλλαγή x = 3 δεν έχει καμία επίπτωση στην τιμή της y.

In [55]:
x = 1
y = x
x = 3
print x, y
3 1

Για να δείτε πώς δουλεύει το προπροηγούμενο πρόγραμμα ένα πολύ καλό εργαλείο είναι το online python tutor. Πηγαίνετε εκεί και πατήστε "Visualize execution", και μετά το κουμπί Forward.