Διαδρομές
/
Python
Python
/
Ασκήσεις
/
Χαρτοπαίγνια
Χαρτοπαίγνια

Χαρτοπαίγνια

Άσκηση εκμάθησης

Εισαγωγή

Η list είναι μια μεταβλητή συλλογή στοιχείων σε σειρά. Όπως οι περισσότερες συλλογές (δες τις ενσωματωμένες tuple, dict και set), οι λίστες μπορούν να κρατήσουν αναφορά σε οποιονδήποτε (ή πολλαπλούς) τύπο δεδομένων, ακόμη και σε άλλες λίστες. Όπως σε κάθε ακολουθία, μπορείς να προσπελάσεις τα στοιχεία μέσω αριθμού 0-based index από τα αριστερά και -1-based index από τα δεξιά. Οι λίστες μπορούν να αντιγραφούν ολόκληρες ή εν μέρει μέσω σημειογραφίας slice ή <list>.copy().

Οι λίστες υποστηρίζουν και κοινές και μεταβλητές λειτουργίες ακολουθίας, όπως min()/max(), <list>.index(), <list>.append() και <list>.reverse(). Μπορείς να επαναλάβεις τα στοιχεία μιας λίστας χρησιμοποιώντας την κατασκευή for item in <list>. Η for index, item in enumerate(<list>) μπορεί να χρησιμοποιηθεί όταν χρειάζεσαι και τη θέση και την τιμή του στοιχείου.

Κάτω από το καπό, οι lists υλοποιούνται ως δυναμικοί πίνακες, παρόμοιοι με τον τύπο ArrayList της Java, και χρησιμοποιούνται συνήθως για την αποθήκευση ομάδων παρόμοιων δεδομένων (συμβολοσειρών, αριθμών, συνόλων κ.λπ.) άγνωστου μήκους. Οι λίστες είναι μια εξαιρετικά ευέλικτη και χρήσιμη δομή δεδομένων και πολλές ενσωματωμένες μέθοδοι και λειτουργίες στην Python παράγουν λίστες ως αποτέλεσμα.

Κατασκευή

Μια list μπορεί να δηλωθεί ως literal με αγκύλες [] και κόμμα ανάμεσα στα στοιχεία:

>>> no_elements = []

>>> no_elements
[]

>>> one_element = ["Guava"]

>>> one_element
['Guava']

>>> elements_separated_with_commas = ["Parrot", "Bird", 334782]

>>> elements_separated_with_commas
['Parrot', 'Bird', 334782]

Για ευκολία στην ανάγνωση, μπορείς να χρησιμοποιήσεις αλλαγές γραμμής όταν υπάρχουν πολλά στοιχεία ή εμφωλευμένες δομές δεδομένων μέσα σε μια list:

>>> lots_of_entries = [
      "Rose",
      "Sunflower",
      "Poppy",
      "Pansy",
      "Tulip",
      "Fuchsia",
      "Cyclamen",
      "Lavender"
   ]
   
>>> lots_of_entries
['Rose', 'Sunflower', 'Poppy', 'Pansy', 'Tulip', 'Fuchsia', 'Cyclamen', 'Lavender']

# Each data structure is on its own line to help clarify what they are.
>>> nested_data_structures = [
      {"fish": "gold", "monkey": "brown", "parrot": "grey"},
      ("fish", "mammal", "bird"),
      ['water', 'jungle', 'sky']
   ]
   
>>> nested_data_structures
[{'fish': 'gold', 'monkey': 'brown', 'parrot': 'grey'}, ('fish', 'mammal', 'bird'), ['water', 'jungle', 'sky']]

Ο κατασκευαστής list() μπορεί να χρησιμοποιηθεί κενός ή με ένα iterable ως όρισμα. Ο κατασκευαστής διατρέχει τα στοιχεία του iterable και τα προσθέτει στη list με τη σειρά:

>>> no_elements = list()

>>> no_elements
[]

# The tuple is unpacked and each element is added.
>>> multiple_elements_from_tuple = list(("Parrot", "Bird", 334782))

>>> multiple_elements_from_tuple
['Parrot', 'Bird', 334782]

# The set is unpacked and each element is added.
>>> multiple_elements_from_set = list({2, 3, 5, 7, 11})

>>> multiple_elements_from_set
[2, 3, 5, 7, 11]

Τα αποτελέσματα όταν χρησιμοποιείς τον κατασκευαστή list με ένα string ή ένα dict μπορεί να σε εκπλήξουν:

# String elements (Unicode code points) are iterated through and added *individually*.
>>> multiple_elements_string = list("Timbuktu")

>>> multiple_elements_string
['T', 'i', 'm', 'b', 'u', 'k', 't', 'u']

# Unicode separators and positioning code points are also added *individually*.
>>> multiple_code_points_string = list('अभ्यास')

>>> multiple_code_points_string
['अ', 'भ', '्', 'य', 'ा', 'स']

# The iteration default for dictionaries is over the keys, so only key data is inserted into the list.
>>> source_data = {"fish": "gold", "monkey": "brown"}

>>> multiple_elements_dict_1 = list(source_data)
['fish', 'monkey']

Επειδή ο κατασκευαστής list δέχεται ως ορίσματα μόνο iterables (ή τίποτα), τα αντικείμενα που δεν είναι iterable πετούν ένα σφάλμα τύπου. Κατά συνέπεια, είναι πολύ πιο εύκολο να δημιουργήσεις μια list με ένα στοιχείο μέσω της literal μεθόδου.

# Numbers are not iterable, and so attempting to create a list with a number passed to the constructor fails.
>>> one_element = list(16)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable

# Tuples *are* iterable, so passing a one-element tuple to the constructor does work, but it's awkward
>>> one_element_from_iterable = list((16,))

>>> one_element_from_iterable
[16]

Προσπέλαση στοιχείων

Τα στοιχεία μέσα στις λίστες (καθώς και τα στοιχεία άλλων τύπων ακολουθίας, όπως str και tuple) μπορούν να προσπελαστούν μέσω 0-based index και σημειογραφίας αγκυλών. Οι θέσεις μπορούν να είναι από left --> right (ξεκινώντας από το μηδέν) ή right --> left (ξεκινώντας από το -1).

θέση από τα αριστερά ⟹






0
👇🏾
1
👇🏾
2
👇🏾
3
👇🏾
4
👇🏾
5
👇🏾
P y t h o n
👆🏾
-6
👆🏾
-5
👆🏾
-4
👆🏾
-3
👆🏾
-2
👆🏾
-1





⟸ θέση από τα δεξιά
>>> breakfast_foods = ["Oatmeal", "Fruit Salad", "Eggs", "Toast"]

# Oatmeal is at index 0 or index -4.
>>> breakfast_foods[0]
'Oatmeal'

>>> breakfast_foods[-4]
'Oatmeal'

# Eggs are at index -2 or 2
>>> breakfast_foods[-2]
'Eggs'

>>> breakfast_foods[2]
'Eggs'

# Toast is at -1
>>> breakfast_foods[-1]
'Toast'

Ένα τμήμα των στοιχείων μέσα σε μια list μπορεί να προσπελαστεί μέσω σημειογραφίας slice (<list>[start:stop]). Ένα slice ορίζεται ως μια ακολουθία στοιχείων στη θέση index, τέτοια ώστε start <= index < stop. Το slicing επιστρέφει ένα αντίγραφο των στοιχείων του slice και δεν τροποποιεί την αρχική list.

Μπορεί επίσης να χρησιμοποιηθεί μια παράμετρος step ([start:stop:step]) για να "προσπεράσεις" ή να φιλτράρεις τα στοιχεία της list (για παράδειγμα, ένα step με τιμή 2 θα επιλέξει κάθε δεύτερο στοιχείο στο εύρος):

>>> colors = ["Red", "Purple", "Green", "Yellow", "Orange", "Pink", "Blue", "Grey"]

# If there is no step parameter, the step is assumed to be 1.
>>> middle_colors = colors[2:6]

>>> middle_colors
['Green', 'Yellow', 'Orange', 'Pink']

# If the start or stop parameters are omitted, the slice will
# start at index zero, and will stop at the end of the list.
>>> primary_colors = colors[::3]

>>> primary_colors
['Red', 'Yellow', 'Blue']

Εργασία με λίστες

Η χρήση της ενσωματωμένης συνάρτησης sum() σε μια λίστα θα επιστρέψει το άθροισμα όλων των αριθμών της λίστας:

>>> number_list = [1, 2, 3, 4]
>>> sum(number_list)
10

Μπορείς επίσης να πάρεις το μήκος μιας λίστας χρησιμοποιώντας τη συνάρτηση len():

>>> long_list = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"]
>>> len(long_list)
10

Οι λίστες μπορούν επίσης να συνδυαστούν με διάφορους τρόπους:

# Using the plus + operator unpacks each list and creates a new list, but it is not efficient.
>>> new_via_concatenate = ["George", 5] + ["cat", "Tabby"]

>>> new_via_concatenate
['George', 5, 'cat', 'Tabby']

# Likewise, using the multiplication operator * is the equivalent of using + n times.
>>> first_group = ["cat", "dog", "elephant"]
>>> multiplied_group = first_group * 3

>>> multiplied_group
['cat', 'dog', 'elephant', 'cat', 'dog', 'elephant', 'cat', 'dog', 'elephant']

Οι λίστες παρέχουν έναν iterator και μπορούν να διατραχθούν σε βρόχο με τον ίδιο τρόπο όπως και οι άλλοι τύποι ακολουθίας.

#  Looping through the list and printing out each element.
>>> colors = ["Orange", "Green", "Grey", "Blue"]

>>> for item in colors:
...     print(item)
...
Orange
Green
Grey
Blue

Για μια πιο αναλυτική εξήγηση των loops και των iterators, ολοκλήρωσε την έννοια loops.

Οδηγίες

Η Elyse ανυπομονεί πραγματικά να παίξει λίγο πόκερ (και άλλα παιχνίδια με κάρτες) στο επερχόμενο ταξίδι της στο Βέγκας. Επειδή είναι λάτρης της "αυτοπαρακολούθησης", θέλει να φτιάξει μερικές μικρές συναρτήσεις που θα τη βοηθήσουν σε εργασίες παρακολούθησης, και σου ζήτησε να τη βοηθήσεις να τις σκεφτείτε μαζί.

1. Παρακολούθηση γύρων πόκερ

Η Elyse έχει ιδιαίτερη αδυναμία στο πόκερ και θέλει να παρακολουθεί πόσους γύρους παίζει, αλλά και ποιοι γύροι είναι αυτοί. Κάθε γύρος έχει τον δικό του αριθμό και κάθε τραπέζι δείχνει τον αριθμό του γύρου που παίζεται εκείνη τη στιγμή. Η Elyse διαλέγει ένα τραπέζι και κάθεται να παίξει τον πρώτο της γύρο. Σκοπεύει να παίξει τρεις γύρους.

Υλοποίησε μια συνάρτηση get_rounds(<round_number>) που παίρνει τον τρέχοντα αριθμό γύρου και επιστρέφει μία μόνο list με αυτόν τον γύρο και τους επόμενους δύο που έρχονται:

>>> get_rounds(27)
[27, 28, 29]

2. Όλοι οι γύροι στο ίδιο μέρος

Η Elyse έπαιξε μερικούς γύρους στο πρώτο τραπέζι, μετά έκανε ένα διάλειμμα και έπαιξε κι άλλους γύρους σε ένα δεύτερο τραπέζι ... αλλά κατέληξε με διαφορετική λίστα για κάθε τραπέζι! Θέλει να ενώσει τις δύο λίστες, ώστε να παρακολουθεί όλους τους γύρους πόκερ στο ίδιο μέρος.

Υλοποίησε μια συνάρτηση concatenate_rounds(<rounds_1>, <rounds_2>) που παίρνει δύο λίστες και επιστρέφει μία μόνο list που αποτελείται από όλους τους γύρους της πρώτης list, ακολουθούμενους από όλους τους γύρους της δεύτερης list:

>>> concatenate_rounds([27, 28, 29], [35, 36])
[27, 28, 29, 35, 36]

3. Εύρεση προηγούμενων γύρων

Μιλώντας για μερικούς από τους προηγούμενους γύρους πόκερ, ένας άλλος παίκτης σχολιάζει πόσο παρόμοια εξελίχθηκαν δύο από αυτούς. Η Elyse δεν είναι σίγουρη αν έπαιξε αυτούς τους γύρους ή όχι.

Υλοποίησε μια συνάρτηση list_contains_round(<rounds>, <round_number>) που παίρνει δύο ορίσματα, μια λίστα με τους γύρους που παίχτηκαν και έναν αριθμό γύρου. Η συνάρτηση θα επιστρέψει True αν ο γύρος υπάρχει στη λίστα με τους γύρους που παίχτηκαν, και False αν όχι:

>>> list_contains_round([27, 28, 29, 35, 36], 29)
True

>>> list_contains_round([27, 28, 29, 35, 36], 30)
False

4. Μέσος όρος των τιμών των καρτών

Η Elyse θέλει να δοκιμάσει ένα νέο παιχνίδι που λέγεται Black Joe. Μοιάζει με το Black Jack, όπου ο στόχος σου είναι οι κάρτες στο χέρι σου να αθροίζουν σε μια τιμή-στόχο, αλλά στο Black Joe ο στόχος είναι ο μέσος όρος των τιμών των καρτών να είναι 7. Ο μέσος όρος βρίσκεται αθροίζοντας όλες τις τιμές των καρτών και μετά διαιρώντας αυτό το άθροισμα με τον αριθμό των καρτών στο χέρι.

Υλοποίησε μια συνάρτηση card_average(<hand>) που θα επιστρέφει τη μέση τιμή ενός χεριού στο Black Joe.

>>> card_average([5, 6, 7])
6.0

5. Εναλλακτικοί μέσοι όροι

Στο Black Joe, η ταχύτητα έχει σημασία. Η Elyse θα προσπαθήσει να βρει έναν πιο γρήγορο τρόπο να υπολογίζει τον μέσο όρο.

Έχει σκεφτεί δύο τρόπους για να βγάλει έναν αριθμό κάτι σαν μέσο όρο:

  • Να πάρει τον μέσο όρο του πρώτου και του τελευταίου αριθμού στο χέρι.
  • Να χρησιμοποιήσει τη διάμεσο (τη μεσαία κάρτα) του χεριού.

Υλοποίησε τη συνάρτηση approx_average_is_average(<hand>), όπου hand είναι μια λίστα που περιέχει τις τιμές των καρτών στο χέρι σου.

Επίστρεψε True αν μία or και οι δύο από τις παραπάνω στρατηγικές δίνουν έναν αριθμό ίσο με τον πραγματικό μέσο όρο.

Σημείωση: Το μήκος όλων των χεριών είναι περιττό, για να είναι πιο εύκολη η εύρεση της διαμέσου.

>>> approx_average_is_average([1, 2, 3])
True

>>> approx_average_is_average([2, 3, 4, 8, 8])
True

>>> approx_average_is_average([1, 2, 3, 5, 9])
False

6. Περισσότερες τεχνικές μέσου όρου

Με αφορμή τα αποτελέσματα του πειράματός της με τους μέσους όρους, η Elyse αναρωτιέται αν ο μέσος όρος των καρτών στις ζυγές θέσεις έναντι του μέσου όρου των καρτών στις μονές θέσεις θα έδινε το ίδιο αποτέλεσμα. Ώρα για άλλη μια συνάρτηση δοκιμής!

Υλοποίησε μια συνάρτηση average_even_is_average_odd(<hand>) που επιστρέφει ένα Boolean (λογική τιμή) που δείχνει αν ο μέσος όρος των καρτών στις ζυγές θέσεις είναι ίδιος με τον μέσο όρο των καρτών στις μονές θέσεις.

>>> average_even_is_average_odd([1, 2, 3])
True

>>> average_even_is_average_odd([1, 2, 3, 4])
False

7. Κανόνες του γύρου μπόνους

Κάθε 11ο χέρι στο Black Joe είναι ένα χέρι μπόνους με έναν κανόνα μπόνους: αν η τελευταία κάρτα που τραβάς είναι Βαλές, διπλασιάζεις την τιμή της.

Υλοποίησε μια συνάρτηση maybe_double_last(<hand>) που παίρνει ένα χέρι και ελέγχει αν η τελευταία κάρτα είναι Βαλές (11). Αν η τελευταία κάρτα είναι Βαλές (11), διπλασίασε την τιμή της πριν επιστρέψεις το χέρι.

>>> hand = [5, 9, 11]
>>> maybe_double_last(hand)
[5, 9, 22]

>>> hand = [5, 9, 10]
>>> maybe_double_last(hand)
[5, 9, 10]
Επεξεργασία μέσω GitHub Ο σύνδεσμος ανοίγει σε νέο παράθυρο ή καρτέλα
Python Exercism

Έτοιμος να ξεκινήσεις την άσκηση Χαρτοπαίγνια;

Γράψου στο Exercism για να μάθεις και να κατακτήσεις Python με 17 έννοιες146 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.