Η εντολή ανακύκλωσης while
είναι η δεύτερη εντολή ανακύκλωσης που βλέπουμε μετά τη for
. Η while
ελέγχει τη συνθήκη της (όπως και το if
) και όσο η συνθήκη είναι True
τότε εκτελούνται οι εντολές που υπάγονται στη while
(οι οποίες είναι γραμμένες σπρωγμένες προς τα μέσα (indented) κάτω από τη while
).
Στο παρακάτω πρόγραμμα τυπώνουμε τους αριθμούς από 1 έως και 10.
Χσρηιμοποιούμε μια μεταβλητή "μετρητή", την i
που έχει αρχικά τιμή 1. Στη συνθήκη του while
ελέγχουμε αν η μεταβλητή αυτή είναι \(\le 10\) και, αν αυτό συμβαίνει, μπαίνουμε στο loop και το i
τυπώνεται και αυξάνεται κατά 1.
i=1
while i <= 10:
print i,
i += 1
Η εντολή ανακύκλωσης while
χρησιμοποιείται φυσιολογικά (αντί για τη for
) όταν δεν είμαστε εκ των προτέρων σίγουροι για το πόσες φορές θα εκτελέσουμε το loop. Στο παρακάτω πρόγραμμα διαβάζουμε ακεραίους από το χρήστη και τους αθροίζουμε κάθε φορά. Όταν ο χρήστης θέλει να σταματήσει τότε μας δίνει τον ακέραιο 0, η οποίος σηματοδοτεί για το πρόγραμμά μας ότι θέλουμε να σταματήσουμε.
Είναι φανερό ότι δε θα είχε νόημα εδώ να χρησιμοποιήσουμε την εντολή for
μια και δε μπορούμε να ξέρουμε από την αρχή πόες φορές θα χρειαστεί να τρέξει η ανακύκλωση.
x = int(raw_input("Give an integer, 0 to finish: "))
s = 0
while x != 0:
s += x
print "The current sum is", s
x = int(raw_input("Give an integer, 0 to finish: "))
print "Bye"
Έστω η συνάρτηση \(f(x) = x^3+x+1\). Θέλουμε, δοθέντος ενός ακεραίου \(y\ge 0\) να αποφασίσουμε αν υπάρχει ακέραιος \(x \ge 0\) τέτοιος ώστε \(f(x)=y\), και αν υπάρχει να βρούμε ποιος είναι. Αφού η συνάρτηση \(f(x)\) είναι γνησίως αύξουσα, ο τρόπος που ακολουθούμε για να το βρούμε είναι ότι αρχίζουμε από την τιμή \(x=0\) και, αυξάνοντας συνεχώς το \(x\) κατά 1, ελέγχουμε αν το \(f(x)\) είναι ακόμη \(< y\).
Όταν αυτό παύει να συμβαίνει τότε ξέρουμε ότι \(y \le f(x)\). Αν ισχύει η ισότητα έχουμε βρει τη (μοναδική) λύση μας, αλλιώς είμαστε σίγουροι (λόγω της μονοτονίας της συνάρτησης) ότι δεν υπάρχει λύση.
Αυτό υλοποιείται παρακάτω με μια ανακύκλωση while
. Στη μεταβλητή f
κρατάμε την τιμή \(f(x)\) για την τρέχουσα τιμή του \(x\) (που βρίσκεται στη μεταβλητή x
).
y = int(raw_input("Give an integer: "))
x = 0
f = 1
while f < y :
print "Examining",x
x += 1
f = x*x*x + x + 1
if f == y:
print "Solution is", x
else:
print "No solution exists"
Παρακάτω αφαιρούμε από μια λίστα όλα τα 2άρια που υπάρχουν μέσα. Η μέθοδος remove
αφαιρεί μόνο το πρώτο 2άρι, οπότε χρειάζονται επανειλημμένες κλήσεις σε αυτήν, όσο εξακολουθεί να υπάρχει 2άρι στη λίστα.
L = input("Please give a list of integers: ")
while 2 in L:
L.remove(2)
Παρακάτω θα δούμε ένα πρόβλημα σχετικά πιο περίπλοκο από αυτά που έχουμε συνηθίσει να βλέπουμε μέχρι τώρα. Η δυσκολία του έγκειται κυρίως στο ότι πολλά από τα δεδομένα μας είναι σε πολύ "φωλιασμένη" (nested, το ένα μέσα στο άλλο) μορφή, πράγμα που κάνει τον κώδικα δύσκολο στην κατανόηση.
Αρχίζουμε με τη λίστα L
που ορίζεται στην πάνω μεριά του προγράμματος. Αυτή η λίστα περιέχει όλη την πληροφορία που θέλουμε, είναι η "βάση δεδομένων" μας. Η λίστα L
περιέχει ένα αντικείμενο για κάθε φοιτητή της μορφής
Για κάθε φοιτητή δηλ. περιέχει μια λίστα, έστω x
, με δύο στοιχεία. Το πρώτο στοιχείο, το x[0]
είναι ένα string, το όνομα του φοιτητή. Το δεύτερο στοιχείο, το x[1]
, είναι μια λίστα. Η λίστα αυτή περιέχει όλα τα μαθήματα στα οποία έχει εγγραφεί ο φοιτητής.
Έτσι, η λίστα L
που δίνεται στο πρόγραμμα περιέχει όλες τις εγγραφές σε μαθήματα για 4 φοιτητές.
Το πρώτο κομμάτι του προγράμματος
students = []; courses=[]
for x in L:
students.append(x[0])
for y in x[1]:
if y not in courses:
courses.append(y)
βρίσκει τη λίστα students
με τα ονόματα όλων των φοιτητών και τη λίστα courses
με τα ονόματα όλων των μαθημάτων που εμφανίζονται. Και οι δύο αυτές λίστες έχουν ως αρχική τιμή την κενή λίστα. Έπειτα διανύουμε τη λίστα L
και για κάθε στοιχείο της (για κάθε φοιτητή δηλ.) ενημερώνουμε τις δύο αυτές λίστες αυξάνοντάς τις κατά το όνομα του φοιτητή την πρώτη και κατά το όνομα του μαθήματος τη δεύτερη. Ειδικά για τη δεύτερη λίστα προσέχουμε να μη ξαναβάλουμε στη λίστα ένα μάθημα αν έχει ήδη μπει εκεί.
Ο κύριος σκοπός του προγράμματος αυτού είναι να "αντιστρέψουμε" κατά κάποιο τρόπο τη μορφή στην οποία είναι αποθηκευμένη η πληροφορία μας. Στη βάση L
η πληροφορία μας είναι αποθηκευμένη κατά φοιτητή. Στη λίστα M
που θα φτιάξουμε η πληφοροφορία θα είναι αποθηκευμένη κατά μάθημα, θα έχει δηλ. η λίστα M
γραμμές της μορφής (μια για κάθε μάθημα)
Σε κάθε γραμμή δηλ. θα αναφέρεται το όνομα ενός μαθήματος και το ποιοι φοιτητές είναι γραμμένοι σε αυτό.
Πρώτα αρχικοποιούμε τη λίστα M
με το παρακάτω:
M = []
for x in courses:
M.append( [x, [] ] )
Έτσι ώστε όλες οι γραμμές της M
είναι πλέον της μορφής
Έχουμε δηλ. βάλει τα ονόματα των μαθημάτων στη θέση τους αλλά οι λίστες με τους εγγεγραμμένους φοιτητές είναι αρχικά κενές, και θα πρέπει να τις γεμίσουμε. Αυτό γίνεται με τον κώδικα
for x in L:
name = x[0]
stcourses = x[1]
for y in stcourses:
for z in M:
if z[0]==y:
z[1].append(name)
break
Ο κώδικας αυτός έχει αρκετό "βάθος", αφού έχει μια ανακύκλωση for
που περιέχει μια άλλη ανακύκλωση for
η οποία περιέχει με τη σειρά της μια άλη ανακύκλωση for
.
Η στρατηγική μας είναι ότι διανύουμε τη λίστα L
(εξωτερικό for
loop), και για κάθε στοιχείο (γραμμή) x
της L
που βρίσκουμε κρατάμε στις μεταβλητές name
και stcourses
το όνομα του φοιτητή και τη λίστα με τα μαθήματά του. Έπειτα για κάθε ένα από τα μαθήματα του φοιτητή, έστω y
(αυτό γίνεται στο μεσαίο for
loop), πρέπει να προσθέσουμε το όνομα του φοιτητή στη λίστα του μαθήματος y
μέσα στη μεγάλη λίστα M
. Εδώ είναι που χρειάζεται το εσωτερικό for
loop όπου διανύουμε τα στοιχεία z
της λίστας Μ
αν το στοιχείο αυτό της M
που έχουμε αντιστοιχεί στο μάθημα y
(το ελέγχουμε με z[0]==y
) τότε προσθέτουμε στη λίστα αυτού του στοιχείου z[1]
το όνομα name
του φοιτητή.
Η λίστα M
που φτιάξαμε τυπώνεται με τον κώδικα:
print "List of courses and registered students follows:"
for x in M:
print x
Στο επόμενο κομμάτι κώδικα
reg = 0
print "---"
print "Number of registered students per course:"
for x in M:
print x[0], len(x[1])
reg += len(x[1])
print "Number of (student, course) pairs:", reg
τυπώνουμε κατ'αρχήν το πόσοι φοιτητές είναι εγγεγραμμένοι σε κάθε μάθημα και, ταυτόχρονα, στο ίδιο for
loop υπολογίζουμε το συνολικό αριθμών ζευγών (φοιτητής, μάθημα στο οποίο εγγράφτηκε) που υπάρχει στη μεταβλητή reg
.
Στο τελευταίο κομμάτι κώδικα:
name1 = raw_input("Give name of course No 1: ")
name2 = raw_input("Give name of course No 2: ")
diff = []
for x in L:
if name1 in x[1] and name2 not in x[1]:
diff.append(x[0])
print diff
Ζητάμε από το χρήστη τα ονόματα δύο μαθημάτων και βρίσκουμε στη λίστα diff
τα ονόματα όλων των φοιτητών που έχουν εγγραφεί στο πρώτο μάθημα αλλά όχι στο δεύτερο.
L = [
[ "Mihalis", ["Prog1", "Calc1", "Foundations"]],
[ "Maria", ["Prog1", "Calc1", "Physics"]],
[ "Yannis", ["Calc1", "Physics", "Foundations", "Prog2"]],
[ "Eleni", ["Calc1", "Physics", "English I"]]
]
students = []; courses=[]
for x in L:
students.append(x[0])
for y in x[1]:
if y not in courses:
courses.append(y)
M = []
for x in courses:
M.append( [x, [] ] )
for x in L:
name = x[0]
stcourses = x[1]
for y in stcourses:
for z in M:
if z[0]==y:
z[1].append(name)
break
print "List of courses and registered students follows:"
for x in M:
print x
reg = 0
print "Number of registered students per course:"
for x in M:
print x[0], len(x[1])
reg += len(x[1])
print "---"
print "Number of (student, course) pairs:", reg
name1 = raw_input("Give name of course No 1: ")
name2 = raw_input("Give name of course No 2: ")
diff = []
for x in L:
if name1 in x[1] and name2 not in x[1]:
diff.append(x[0])
print diff