Σήμερα μιλήσαμε κυρίως για αρχεία, list comprehensions και για dictionaries.
Στο παρακάτω παράδειγμα ανοίγουμε ένα αρχείο με όνομα alice.txt
για διάβασμα (μπορείτε να κατεβάσετε αυτό το αρχείο από τη θέση αυτή και να το αποθηκεύσετε στον υπολογιστή σας) και βρίσκουμε το πόσες γραμμές έχει. Με τη μέθοδο f.readlines()
παίρνουμε πίσω μια λίστα της οποίας τα στοιχεία είναι οι γραμμές του αρχείου, ένα string η κάθε μία. Έτσι η ποσότητα len(f.readlines())
είναι το μήκος της λίστας αυτής, δηλ. το πλήθος των γραμμών του αρχείου. Τέλος κλείνουμε το αρχείο (έτσι πρέπει πάντα να κάνουμε αφού τελειώσουμε με αυτό).
f = open("alice.txt", "r")
print len(f.readlines())
f.close()
Στο επόμενο τυπώνουμε τις 20 πρώτες γραμμές του αρχείου. Παρατηρείστε ότι οι γραμμές αυτές χωρίζονται από μια κενή γραμμή επιπλέον, ενώ στο αρχείο δεν είναι έτσι. Ο λόγος είναι ότι το string που διαβάζουμε για κάθε γραμμή τελειώνει με τον ειδικό χαρακτήρα newline ('\n'
) και επειδή χρησιμοποιούμε τη συνάρτηση print
για να τυπώσουμε η οποία ούτως ή άλλως αλλάζει γραμμή προκύπτουν δύο αλλαγές γραμμών μετά από το τύπωμα κάθε γραμμής. Μια λύση σε αυτό το πρόβλημα είναι να γράψουμε την τελευταία εντολή ως print ll[i],
f = open("alice.txt", "r")
ll = f.readlines()
for i in range(20):
print ll[i]
Στο παρακάτω βλέπουμε πώς μπορούμε να απαλλαγούμε από τον τελευταίο χαρακτήρα των string που έχουν τα περιεχόμενα των γραμμών του αρχείου, το χαρακτήρα newline. Μία λύση είναι να χρησιμοποιήσουμε τη μέθοδο s.rstrip()
που μας επιστρέφει το string s
αφού πρώτα σβήσει από το τέλος του string όλους τους λευκούς χαρακτήρες. Αυτοί είναι οι ' '
(κενό ή space), '\n'
(newline), '\t'
(tab). Προσοχή, αν δε θέλουμε να σβήσουμε και τους όποιους άλλους λευκούς χαρακτήρες από το τέλος του string δεν πρέπει να χρησιμοποιήσουμε τον τρόπο αυτό. Μια άλλη μέθοδος είναι να αντικαταστήσουμε την τελευταία γραμμή με την print s[0:len(s)-1]
, που τυπώνει το string μείον ένα τελευταίο χαρακτήρα.
f = open("alice.txt", "r")
ll = f.readlines()
for s in ll:
print s.rstrip()
Στο επόμενο κελλί υπολογίζουμε ποια είναι η μεγαλύτερη (σε αριθμό χαρακτήρων) γραμμή του αρχείου. Στη λίστα n
υπολογίζουμε τα μήκη όλων των γραμμών του αρχείου και στην τελευταία γραμμή τυπώνουμε το μέγιστο.
f = open("alice.txt", "r")
ll = f.readlines()
n = []
for i in ll:
n.append(len(i))
print max(n)
Εδώ βλέπουμε ένα νέο τρόπο, πιο βολικό και σύντομο μερικές φορές, να δημιουργήσουμε μια λίστα περιγράφοντας τα στοιχεία της σχεδόν όπως το κάνουμε όταν περιγράφουμε ένα σύνολο στα Μαθηματικά.
Στο πρόγραμμα παρακάτω, που κάνει την ίδια δουλειά με το προηγούμενο, βλέπουμε πώς η λίστα των μηκών των γραμμών του αρχείου περιγράφεται ως
[len(x) for x in ll]
Αυτό είναι ένα παράδειγμα ενός list comprehension παραδείγματα από το οποίο μπορείτε π.χ. να δείτε εδώ.
f = open("alice.txt", "r")
ll = f.readlines()
print max([len(x) for x in ll])
Εδώ βλέπουμε άλλο ένα παράδειγμα ενός list comprehension, στο οποίο παράγουμε μια λίστα που αποτελείται από όλα τα ζεύγη \(x, y\) με \(x, y \in \{0, 1, 2, 3, 4\}\) (κάθε ζεύγος είναι κι αυτό μια λίστα μήκους 2).
print [[x,y] for x in range(5) for y in range(5)]
Στο επόμενο υπολογίζουμε το άθροισμα όλων των μηκών των γραμμών του αρχείου. Η συνάρτηση sum
μιας λίστας επιστρέφει το άθροισμα των στοιχείων της.
f = open("alice.txt", "r")
ll = f.readlines()
print sum([len(x) for x in ll])
Εδώ θέλουμε να βρούμε όλες τις λέξεις που εμφανίζονται στο αρχείο, μία φορά την κάθε μία. Για τους σκοπούς αυτής της άσκησης λέξη είναι ό,τι δεν έχει μέσα κενό χαρακτήρα.
Αφού διαβάσουμε όλες τις γραμμές στη λίστα ll
περνάμε όλες αυτές από τη μέθοδο strip
ώστε να τους αφαιρέσουμε το τελικό newline (και τους όποιους τελικούς λευκούς χαρακτήρες) και αποθηκεύουμε το αποτέλεσμα στη λίστα l
.
Αν x
είναι ένα string τότε η μέθοδος x.split()
επιστρέφει μια λίστα με strings, που είναι ό,τι προκύπτει από το string x
αν θεωρήσουμε τους λευκούς χαρακτήρες ως διαχωριστικούς. Έτσι η εντολή
ll = [x.split() for x in l]
κάνει τη λίστα ll
(δεν πειράζει που ξαναχρησιμοποιούμε το όνομα) να είναι μια λίστα από λίστες. Κάθε μια από αυτές τις λίστες είναι οι λέξεις μιας γραμμής.
Σκοπός μας είναι να βρούμε όλες τις λέξεις που εμφανίζονται στο αρχείο και θα τις τοποθετήσουμε (μία φορά την κάθε μία) στη λίστα allwords
η οποία είναι αρχικά κενή. Με το διπλό loop που ακολουθεί τοποθετούμε κάθε ένα από τα strings που βρίσκονται στις λίστες που περιέχονται στην ll
μέσα στη λίστα allwords
αν δεν είναι ήδη μέσα.
Τέλος αναφέρουμε το πόσες διαφορετικές λέξεις βρήκαμε και τυπώνουμε τη λίστα allwords
.
f = open("alice.txt", "r")
ll = f.readlines()
f.close()
l = [x.rstrip() for x in ll]
ll = [x.split() for x in l]
allwords = []
for line in ll:
for s in line:
if not(s in allwords):
allwords.append(s)
allwords.sort()
print "Found {N} different words".format(N=len(allwords))
print allwords
Ένα dictionary (δείτε π.χ. εδώ) στην python είναι σα μια λίστα, χωρίς εσωτερική διάταξη, που τα στοιχεία της γίνονται indexed όχι κατ' ανάγκη από φυσικούς αριθμούς αλλά και από λέξεις. Τα περιεχόενα ενός λεξικού είναι ζεύγη της μορφής
key: object
όπου το κλειδί key
μπορεί να είναι αριθμός ή string και το object μπορεί να είναι οτιδήποτε. Για κάθε κλειδί πρέπει να υπάρχει ένα μοναδικό ζεύγος (αν γράψουμε κι άλλο επικρατεί το τελευταίο στη σειρά).
Στο παρακάτω παράδειγμα βλέπουμε ένα λεξικό με όνομα age
, τα ζεύγη του οποίου είναι της μορφής "όνομα: ηλικία". Παρατηρείστε ότι στον ορισμό του λεξικού χρησιμοποιούμε άγκιστρα {}
και όχι αγκύλες []
όπως κάνουμε για τις λίστες. Όταν όμως αναφερόμαστε σε κάποιο στοιχείο όπως κάνουμε στη δεύτερη και στην τρίτη γραμμή του προγράμματος τότε χρησιμοποιούμε αγκύλες.
age = {"Mihalis": 48, "Manolis": 50, "Nikos": 12}
age["Nikos"] += 2
print age["Nikos"]
print age
Εδώ βλέπουμε στη δεύτερη γραμμή το πώς ελέγχουμε αν ένα κλειδί "Yannis"
υπάρχει σε ένα λεξικό. Αν δεν υπάρχει το προσθέτουμε με ηλικία 55 ενώ αν υπάρχει τυπώνουμε την ηλικία του (συμβαίνει το πρώτο). Στην προτελευταία γραμμή διαγράφουμε το ζεύγος με key "Manolis"
από το λεξικό με την εντολή del
.
age = {"Mihalis": 48, "Manolis": 50, "Nikos": 12}
if "Yannis" in age:
print age["Yannis"]
else:
age["Yannis"] = 55
del age["Manolis"]
print age
Στο επόμενο πρόγραμμα χρησιμοποιούμε ένα λεξικό για να μετρήσουμε για κάθε λέξη του αρχείου μας πόσες φορές αυτή εμφανίζεται. Όπως και στο προηγούμενο πρόγραμμά μας (που έβρισκε όλες τις λέξεις) έχουμε στη γραμμή 6 στη μεταβλητή ll
μια λίστα από λίστες λέξεων.
Δημιουργούμε ένα κατ' αρχήν κενό λεξικό d={}
και στο επόμενο διπλό loop ελέγχουμε αν το string s
είναι στο λεξικό. Αν δεν είναι τότε το βάζουμε με αριθμό εμφανίσεων ίσο με 1 (στη γραμμή d[s] = 1
) ενώ αν είναι ήδη μέσα τότε αυξάνουμε την τιμή του κατά 1 με την εντολή d[s] += 1
.
Θέλουμε επίσης να βρούμε τη λέξη του αρχείου με το μεγαλύτερο αριθμό εμφανίσεων οπότε χρησιμοποιούμε τη μεταβλητή m
για το τρέχον μέγιστο (όπως θα διανύουμε το λεξικό) και τη μεταβλητή onoma
για τη λέξη με το τρέχον μέγιστο. Δίνουμε δύο αρχικές τιμές σε αυτές τις μεταβλητές και μετά διανύουμε το λεξικό με το for key in d:
ούτως ώστε το key
να πάρει διαδοχικά ως τιμή όλα τα διαφορετικά κλειδιά που εμφανίζονται στο d
. Αν πρέπει να αλλάξουμε το τρέχον μέγιστο το κάνουμε αυτό στη γραμμή μετά το if
.
Με το προτελευταίο print
τυπώνουμε το ποια είναι αυτή η λέξη και το πόσες φορές εμφανίζεται και με το τελευταίο print
τυπώνουμε όλες τις λέξεις μαζί με τους αριθμούς εμφάνισής τους.
f = open("alice.txt", "r")
ll = f.readlines()
f.close()
l = [x.rstrip() for x in ll]
ll = [x.split() for x in l]
d={}
for line in ll:
for s in line:
if not( s in d ):
d[s] = 1
else:
d[s] += 1
m=0
onoma = ""
for key in d:
if d[key] > m:
m = d[key]; onoma = key
print "Max word appearance: \"{s}\" appears {M} times".format(s=onoma,M=m)
print d
Εδώ επεξεργαζόμαστε ένα διαφορετικό αρχείο (μπορείτε να το κατεβάσετε από εδώ και να το αποθηκεύσετε στον υπολογιστή σας). Σκοπός είναι να μετρήσουμε σε πόσες γραμμές του αρχείου αυτού εμφανίζεται η λέξη ERROR.
Αφού πάρουμε, όπως πριν, στη λίστα ll
όλες τις γραμμές του αρχείου (ένα string η κάθε μία) θέτουμε το μετρητή count
ίσο με το 0 και για κάθε γραμμή του αρχείου (for s in ll:
) χρησιμοποιούμε τη μέθοδο s.find("ERROR")
για να αποφασίσουμε αν το string "ERROR"
υπάρχει ως substring στο s. Η μέθοδος find
επιστρέφει -1 αν δε βρεθεί το string οπότε αρκεί να ελέγξουμε ότι η τιμή που επιστρέφει είναι διαφορετική από -1 για να ξέρουμε αν εμφανίζεται το "ERROR"
.
f = open("scores-0-min-max.csv", "r")
lines = f.readlines()
f.close()
ll = [s.rstrip() for s in lines]
count=0
for s in ll:
if s.find("ERROR") != -1:
count += 1
print "Number of errors:", count