Στο επόμενο βλέπετε ένα παράδειγμα λίστας. Τα στοιχεία της δε χρειάζεται να είναι ομοιογενή όπως βλέπετε.
l = [1, 2, 3, 'abc', 1.1]
print l
Κάποια στοιχεία μιας λίστας μπορούν να είναι ακόμη και άλλες λίστες. Το τελευταίο στοιχείο της λίστας l
είναι η λίστα [0.1, 2.3]
.
l = [1, 2, 3, 'abc', 1.1, [0.1, 2.3] ]
print l
Το παρακάτω κάνει την ίδια δουλειά με το προηγούμενο, απλά χρησιμοποιεί μια ενδιάμεση μεταβλητή ll
για να ορίσει τη λίστα [0.1, 2.3]
.
ll = [0.1, 2.3]
l = [1, 2, 3, 'abc', 1.1, ll ]
print l
Εδώ βλέπετε μια κενή λίστα, και βλέπετε επίσης ότι το μήκος της είναι 0. Κενές λίστες χρησιμοποιούνται συχνά ως αρχικές τιμές σε μια μεταβλητή τύπου λίστας που σιγά-σιγά μεγαλώνει προσθέτοντας στοιχεία σε αυτή.
e = []
print e
print len(e)
Εδώ βλέπουμε πώς χρησιμοποιούμε slices (φέτες) σε λίστες για να πάρουμε μια υπολίστα αυτών. Τα slices γράφονται ακριβώς όπως και στα strings.
l = [1, 2, 3, 'abc', 1.1, [0.1, 2.3] ]
x = l[2:5]
print x
l = [1, 2, 3, 'abc', 1.1, [0.1, 2.3] ]
x = l[2:5:2]
print x
l = [1, 2, 3, 'abc', 1.1, [0.1, 2.3] ]
x = l[:5:2]
print x
x = l[2::2]
print x
x = l[::-1]
print x
Βλέπουμε εδώ πώς μπορούμε να φτιάξουμε αντίγραφο μιας λίστας. Η εντολή y = x[:]
αντιγράφει τη λίστα στην οποία δείχνει η μεταβλητή x
σε μια νέα περιοχή στη μνήμη και βάζει τη μεταβλητή y
να δείχνει σε αυτήν. Έτσι μια οποιαδήποτε αλλαγή στη λίστα x
(όπως η αμέσως επόμενη εντολή x[0] = 10
που αλλάζει το πρώτο στοιχείο της λίστας x
σε 10) δεν έχει καμιά επίπτωση στη λίστα y
, όπως φαίνεται και από το τι τυπώνεται.
Αν στο παρακάτω πρόγραμμα αντικαταστήσετε την εντολή y = x[:]
με την εντολή y = x
(η οποία κάνει το όνομα y
να δείχνει όπου και το όνομα x
) το αποτέλεσμα θα είναι διαφορετικό (δοκιμάστε το). Η αλλαγή που κάνουμε στη λίστα x
θα συμβεί και στη λίστα y
, αφού και τα δύο ονόματα δείχνουν στις ίδιες θέσεις στη μνήμη.
x = [1, 2, 3]
y = x[:]
x[0] = 10
print x
print y
Στο παρακάτω βλέπουμε τη χρήση αρνητικών δεικτών σε μια λίστα. Αν L
είναι το μήκος (πλήθος στοιχείων) μιας λίστας τότε ο δείκτης -1
είναι το ίδιο με τον L-1
, ο δείκτης -2
ίδιος με το δείκτη L-2
κλπ. Έτσι το τελευταίο στοιχείο της λίστας l
μπορεί να γραφεί είτε ως l[L-1]
είτε ως l[-1]
(όπου L
είναι το μήκος της l
).
l = [1, 2, 3, 'abc', 1.1, [0.1, 2.3] ]
print l[-1]
Για να προσθέσουμε ένα στοιχείο στο τέλος μιας λίστας χρησιμοποιούμε τη μέθοδο append
.
lista = [1, 2, 3, 'abc', 1.1, [0.1, 2.3] ]
lista.append("Mihalis")
print lista
Για να συγκολλήσουμε δύο λίστες μπορούμε να χρησιμοποιήσουμε τον τελεστή +
.
l = [1, 2, 3, 'abc', 1.1, [0.1, 2.3] ]
l = l+['a', 'b', 'c']
print l
Για να προσθέσουμε μια ολόκληρη λίστα στο τέλος μιας λίστας χρησιμοποιούμε τη μέθοδο extend
.
l = [1, 2, 3, 'abc', 1.1, [0.1, 2.3] ]
ll = ['a', 'b', 'c']
l.extend(ll)
print l
Για να εισαγάγουμε ένα στοιχείο σε μια θέση της λίστας χρησιμοποιούμε τη μέθοδο insert
και ως πρώτο όρισμα στην insert
δίνουμε το δείκτη που θέλουμε να έχει το στοιχείο που θέλουμε να εισαγάγουμε (δεύτερο όρισμα στην insert
).
l = [1, 2, 3, 'abc', 1.1, [0.1, 2.3] ]
l.insert(4, "Mihalis")
print l
Αντί για insert
στη θέση 0 μπορούμε να χρησιμοποιήσουμε τον τελεστή +
όπως φαίνεται στο επόμενο.
l = [1, 2, 3, 'abc', 1.1, [0.1, 2.3] ]
l = ['Mihalis'] + l
print l
Ο τελεστής in
χρησιμοποιείται για να ελέγξουμε αν ένα στοιχείο είναι στοιχείο μιας λίστας ή όχι.
l = [1, 2, 3, 'abc', 1.1, [0.1, 2.3] ]
print 4 in l
Αν γνωρίζουμε ότι ένα στοιχείο είναι σε μια λίστα τότε μπορούμε να μάθουμε την πρώτη θέση του στη λίστα (μπορεί να εμφανίζεται παραπάνω από μια φορά) με τη μέθοδο index
. Αν το στοιχείο με το οποίο καλούμε την index
δεν είναι στη λίστα τότε δημιουργείται σφάλμα, οπότε πρέπει πρώτα να χρησιμοποιούμε τον τελεστή in
για να ελέγχουμε αν κάτι είναι μέσα στη λίστα πριν αναζητήσουμε τη θέση του.
l = [1, 2, 3, 'abc', 1.1, [0.1, 2.3] ]
print l.index('abc')
l = [1, 2, 3, 'abc', 1.1, [0.1, 2.3] ]
print l.index('abcd')
Στο παρακάτω πρόγραμμα ζητάμε μια λίστα από το χρήστη και ένα αριθμό και απαντάμε με τη θέση του αριθμού στη λίστα προσέχοντας μην τύχει και ο αριθμός δεν είναι στη λίστα. Παρατηρείστε πώς διαβάζουμε μια λίστα από το χρήστη και πώς ο χρήστης δίνει τη λίστα κατά το τρέξιμο του προγράμματος.
L = input("Give me a list: ")
x = int(raw_input("Give an integer: "))
if x in L:
n = L.index(x)
print "The number %d is in the list. First location %d." % (x, n)
else:
print "The number %d is not in the list." % (x)
Με τη μέθοδο remove
διαγράφουμε από τη λίστα ένα στοιχείο της, δίνοντας το όνομα (όχι τη θέση) του στοιχείου. Διαγράφεται μόνο η πρώτη εμφάνιση του στοιχείου στη λίστα. Αν το στοιχείο δεν είναι στη λίστα δημιουργείται σφάλμα.
l = [1, 2, 3, 'abc', 2, [0.1, 2.3] ]
l.remove('abc')
print l
Ενώ με την εντολή del
διαγράφουμε ένα στοιχείο από τη λίστα δίνοντας τη θέση του.
l = [1, 2, 3, 'abc', 2, [0.1, 2.3] ]
del l[4:6]
print l
Με τη συνάρτηση range
δημιουργούμε μια λίστα ακεραίων.
Με το range(N)
δημιουργούμε τη λίστα [0, 1, ... , Ν-1]
.
Με το range(M, N)
δημιουργούμε τη λίστα [Μ, Μ+1, ... , Ν-1]
.
Με το range(M, N, S)
δημιουργούμε τη λίστα [M, M+S, M+2S, ...]
. Η λίστα εκτείνεται όσο τα στοιχεία της είναι μικρότερα (αυστηρά) από N
.
print range(5)
print range(4, 8)
print range(4, 24, 3)
Πολύ χρήσιμες συναρτήσεις για λίστες είναι και οι min
, max
και sum
που υπολογίζουν το ελάχιστο στοιχείο, μέγιστο στοιχείο και άθροισμα στοιχείων μιας (αριθμητικής) λίστας.
l = [1, 2, 3.1]
m = min(l)
M = max(l)
s = sum(l)
print m, M, s
Με την εντολή for x in L:
διατρέχουμε με τη μεταβλητή x
τα στοιχεία της λίστας L
. Αυτό σημαίνει ότι οι εντολές που υπάγονται στο for
(και είναι ακριβώς από κάτω και σπρωγμένες (indented) προς τα μέσα) θα εκτελεστούν μια φορά για κάθε στοιχείο της λίστας και σε κάθε τέτοια εκτέλεση η μεταβλητή x
θα περιέχει ακριβώς το στοιχείο αυτό της λίστας.
Τη μεταβλητή της λίστας δεν την τροποποιούμε μέσα στην ανακύκλωση for
παρά μόνο διαβάζουμε την τιμή της και τη χρησιμοποιούμε.
Η εντολή for
είναι η πρώτη εντολή ανακύκλωσης (επανειλημμένης εκτέλεσης δηλ.) που συναντάμε και είναι πάρα πολύ σημαντική. Μέχρι τώρα σε όλα τα προγράμματα που γράφαμε όλες οι εντολές τους εκτελούνταν το πολύ μια φορά η κάθε μία. Αυτό από μόνο του περιορίζει πολύ το πόσο χρήσιμο μπορεί να είναι ένα τέτοιο πρόγραμμα. Με την εντολή for
τα προγράμματά μας πλέον γίνονται πολύ πιο ισχυρά, πιο ενδιαφέροντα και, συνήθως, πιο δύσκολα στην κατανόησή τους.
L = ['Manolis', 'Mihalis', 'Yannis']
for x in L:
print x
Στο επόμενο τυπώνουμε όλα τα τετράγωνα ακεραίων από 1 έως 10. Το κόμμα μετά το print
σημαίνει ότι το print
δε θα αλλάξει γραμμή.
L = range(1,11)
for x in L:
print x**2,
Το ίδιο κάνει και αυτό το πρόγραμμα μόνο που τυπώνει το \(x\) μαζί με το \(x^2\).
for x in range(1, 11):
print "The square of %d is %d." % (x, x**2)
Το πρόγραμμα που ακολουθεί είναι κατά πολύ το χρησιμότερο και δυσκολότερο που έχουμε γράψει μέχρι τώρα. Ζητάει από το χρήστη ένα φυσικό αριθμό \(n > 1\) και αποφασίζει αν ο αριθμός είναι πρώτος (δεν έχει γνήσιους διαιρέτες) ή όχι (γνήσιος διαιρέτης ενός αριθμού είναι κάθε διαιρέτης εκτός από τον εαυτό του και το 1).
Για να αποφασίσουμε αν ο \(n\) είναι πρώτος διατρέχουμε όλους τους ακεραίους από 2 έως \(n-1\) και ελέγχουμε αν κάποιος από αυτούς διαιρεί τον \(n\). Αν βρούμε έστω και έναν τότε ο αριθμός δεν είναι πρώτος (λέμε ότι είναι σύνθετος) αν δε βρούμε κανένα τότε είναι πρώτος.
Για το λόγο αυτό χρησιμοποιούμε μια λογική μεταβλητή isprime
, κατ' αρχήν True
, που αντικατοπτρίζει το τι πιστεύουμε για τον αριθμό \(n\) με βάση τα όσα έχουμε δει μέχρι κάποια χρονική στιγμή. Στην αρχή δεν έχουμε δει κάποιο λόγο να θεωρήσουμε το \(n\) σύνθετο οπότε αρχικά υποθέτουμε ότι είναι πρώτος. Αν κάποια στιγμή αργότερα βρούμε ένα διαιρέτη του \(n\) τότε η μεταβλητή αυτή γίνεται False
και παραμένει False
. Στο τέλος της ανακύκλωσης βρίσκεται στη μεταβλητή isprime
η απάντηση στην ερώτηση αν το \(n\) είναι πρώτος ή όχι.
Στην ανακύκλωση
for k in range(2, n):
if n % k == 0:
isprime = False
διατρέχουμε όλους τους ακεραίους στη λίστα range(2,n)
, δηλ. στη λίστα [2, 3, 4, ... , n-1]
και ελέγχουμε αν κάποιος από αυτούς τους αριθμούς διαιρεί το n
. Αν αυτό συμβεί τότε η μεταβλητή isprime
γίνεται False
(αυτό μπορεί να συμβεί πολλές φορές, μια για κάθε διαιρέτη που βρίσκουμε).
Μετά την ανακύκλωση τυπώνουμε το ανάλογο μήνυμα.
Πρόβλημα για εσάς Εύκολα μπορεί κανείς να αποδείξει, με απαγωγή σε άτοπο, ότι ένας φυσικός αριθμός \(n\) που είναι σύνθετος έχει σίγουρα κάποιο γνήσιο διαιρέτη που είναι \(\le \sqrt{n}\). Αυτό σημαίνει ότι δε χρειάζεται να κάνουμε τόσους ελέγχους όσους κάνει το παραπάνω πρόγραμμα για να βεβαιωθούμε ότι ο \(n\) είναι πρώτος (το παραπάνω πρόγραμμα κάνει \(n-3\) ελέγχους). Γράψτε ένα παρόμοιο πρόγραμμα που εκμεταλλεύεται την ιδιότητα αυτή και άρα κάνει πολύ λιγότερους ελέγχους διαιρετότητας, μια διαφορά που μπορεί να έχει μεγάλες επιπτώσεις στο χρόνο τρεξίματος του προγράμματος αν το \(n\) είναι μεγάλο.
n = int(raw_input("Give me a positive integer > 1: "))
isprime = True
for k in range(2, n):
if n % k == 0:
isprime = False
if isprime:
print "The number %d is a prime." % (n)
else:
print "The number %d is not a prime." % (n)
Το επόμενο πρόγραμμα είναι μια τροποποίηση του προηγούμενου που όχι μόνο μας λέει αν ο αριθμός \(n\) είναι πρώτος ή σύνθετος αλλά, στην περίπτωση που είναι σύνθετος, μας δίνει και τη λίστα των διαιρετών του \(n\).
Για το σκοπό χρησιμοποιούμε τη λίστα divisors
, αρχικά κενή, στην οποία μέσα βάζουμε (με τη μέθοδο append
) κάθε διαιρέτη που βρίσκουμε (με την εντολή divisors.append(k)
που εκτελείται μόνο όταν εκτελεστεί το if
που είναι μέσα στην ανακύκλωση.
Στο τέλος, στην περίπτωση που ο \(n\) είναι σύνθετος, τυπώνουμε όλους τους διαιρέτες του χρησιμοποιώντας και πάλι μια ανακύκλωση for
για να διατρέξουμε τη λίστα divisors
.
n = int(raw_input("Give me a positive integer > 1: "))
isprime = True
divisors = []
for k in range(2, n):
if n % k == 0:
isprime = False
divisors.append(k)
if isprime:
print "The number %d is a prime." % (n)
else:
print "The number %d is not a prime." % (n)
print "The list of divisors is: ",
for x in divisors:
print x,