Σύ

Σύνολα σε Python

16 ασκήσεις

Σχετικά με την έννοια Σύνολα

Ένα set είναι μια μεταβλητή και μη διατεταγμένη συλλογή από hashable αντικείμενα. Τα μέλη ενός συνόλου πρέπει να είναι διακριτά. Τα διπλότυπα στοιχεία δεν επιτρέπονται. Μπορούν να περιέχουν πολλούς διαφορετικούς τύπους δεδομένων και ακόμη και εμφωλευμένες δομές, όπως ένα tuple από tuples, αρκεί όλα τα στοιχεία να μπορούν να γίνουν hashed. Τα σύνολα διατίθενται επίσης σε μια αμετάβλητη εκδοχή, το frozenset.

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

Όπως και οι άλλοι τύποι συλλογών (λεξικά, λίστες, tuples), τα sets υποστηρίζουν:

  • Επανάληψη μέσω for item in <set>,
  • Έλεγχο συμμετοχής μέσω in και not in,
  • Υπολογισμό μήκους μέσω len(), και
  • Ρηχά αντίγραφα μέσω copy().

Τα sets δεν υποστηρίζουν:

  • Προσπέλαση με θέση, οποιουδήποτε είδους
  • Διάταξη μέσω ταξινόμησης ή εισαγωγής
  • Τεμαχισμό
  • Συνένωση μέσω +

Ο έλεγχος συμμετοχής σε ένα set έχει σταθερή πολυπλοκότητα χρόνου (κατά μέσο όρο), ενώ ο έλεγχος συμμετοχής σε μια list ή string έχει πολυπλοκότητα χρόνου που αυξάνεται όσο μεγαλώνει το μήκος των δεδομένων. Μέθοδοι όπως <set>.union(), <set>.intersection() ή <set>.difference() έχουν επίσης σταθερή πολυπλοκότητα χρόνου (κατά μέσο όρο).

Δημιουργία Συνόλων

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

Κυριολεκτικά Σύνολα

Ένα set μπορεί να εισαχθεί απευθείας ως κυριολεκτικό σύνολο με άγκιστρα {} και κόμματα μεταξύ των στοιχείων. Τα διπλότυπα παραλείπονται σιωπηλά:

>>> one_element = {'➕'}
{'➕'}

>>> multiple_elements = {'➕', '🔻', '🔹', '🔆'}
{'➕', '🔻', '🔹', '🔆'}

>>> multiple_duplicates =  {'Hello!', 'Hello!', 'Hello!', 
                            '¡Hola!','Привіт!', 'こんにちは!', 
                            '¡Hola!','Привіт!', 'こんにちは!'}
{'こんにちは!', '¡Hola!', 'Hello!', 'Привіт!'}

Τα κυριολεκτικά σύνολα χρησιμοποιούν τα ίδια άγκιστρα με τα κυριολεκτικά dict, που σημαίνει ότι χρειάζεται να χρησιμοποιήσεις το set() για να δημιουργήσεις ένα κενό set.

Ο Κατασκευαστής Συνόλων

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

# To create an empty set, the constructor must be used.
>>> no_elements = set()
set()

# The tuple is unpacked & each element is added.  
# Duplicates are removed.
>>> elements_from_tuple = set(("Parrot", "Bird", 
                               334782, "Bird", "Parrot"))
{334782, 'Bird', 'Parrot'}

# The list is unpacked & each element is added.
# Duplicates are removed.
>>> elements_from_list = set([2, 3, 2, 3, 3, 3, 5, 
                              7, 11, 7, 11, 13, 13])
{2, 3, 5, 7, 11, 13}

Κατανοήσεις Συνόλων

Όπως τα lists και τα dicts, τα σύνολα μπορούν να δημιουργηθούν μέσω κατανόησης:

# First, a list with duplicates
>>> numbers = [1,2,3,4,5,6,6,5,4,8,9,9,9,2,3,12,18]

# This set comprehension squares the numbers divisible by 3
# Duplicates are removed.
>>> calculated = {item**2 for item in numbers if item % 3 == 0}
{9, 36, 81, 144, 324}

Παγίδες κατά τη Δημιουργία Συνόλων

Λόγω της συμπεριφοράς "αποσυσκευασίας" του, η χρήση του κατασκευαστή set με μια συμβολοσειρά μπορεί να εκπλήξει:

# String elements (Unicode code points) are 
# iterated through and added *individually*.
>>> elements_string = set("Timbuktu")
{'T', 'b', 'i', 'k', 'm', 't', 'u'}

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

Θυμήσου: τα σύνολα μπορούν να περιέχουν διαφορετικούς τύπους δεδομένων και εμφωλευμένους τύπους δεδομένων, αλλά όλα τα στοιχεία ενός set πρέπει να είναι hashable:

# Attempting to use a list for a set member throws a TypeError
>>> lists_as_elements = {['🌈','💦'], 
                        ['☁️','⭐️','🌍'], 
                        ['⛵️', '🚲', '🚀']}

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'


# Standard sets are mutable, so they cannot be hashed.
>>> sets_as_elements = {{'🌈','💦'}, 
                        {'☁️','⭐️','🌍'}, 
                        {'⛵️', '🚲', '🚀'}}

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'

Ωστόσο, ένα set από sets μπορεί να δημιουργηθεί μέσω του τύπου frozenset():

# Frozensets don't have a literal form.
>>> set_1 = frozenset({'🌈','💦'})
>>> set_2 = frozenset({'☁️','⭐️','🌍'})
>>> set_3 = frozenset({'⛵️', '🚲', '🚀'})

>>> frozen_sets_as_elements = {set_1, set_2, set_3}
>>> frozen_sets_as_elements
{frozenset({'⛵️', '🚀', '🚲'}),
 frozenset({'🌈', '💦'}),
 frozenset({'☁️', '⭐️', '🌍'})}

Προσθήκη και Αφαίρεση Μελών Συνόλου

Τα στοιχεία μπορούν να προστεθούν ή να αφαιρεθούν από ένα set χρησιμοποιώντας τις μεθόδους <set>.add(<item>) και <set>.remove(<item>). Η μέθοδος .remove(<item>) θα πετάξει ένα KeyError αν το στοιχείο δεν υπάρχει στο set:

>>> creatures = {'crow', 'duck', 'fish', 'monkey', 'elephant'}
>>> creatures.add('beaver')
>>> creatures.remove('duck')
>>> creatures
{'beaver', 'crow', 'elephant', 'fish', 'monkey'}

# Trying to remove an item that is not present raises a KeyError
>>> creatures.remove('bear')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  KeyError: 'bear'

Πρόσθετες Στρατηγικές για την Αφαίρεση Μελών Συνόλου

  • Το <set>.discard(<item>) θα αφαιρέσει ένα στοιχείο από το set, αλλά δεν θα πετάξει KeyError αν το στοιχείο δεν υπάρχει.
  • Το <set>.clear() θα αφαιρέσει όλα τα στοιχεία από το σύνολο.
  • Το <set>.pop() θα αφαιρέσει και θα επιστρέψει ένα αυθαίρετο στοιχείο, και πετάει ένα KeyError αν το set είναι κενό.

Πράξεις Συνόλων

Τα σύνολα έχουν μεθόδους που γενικά μιμούνται τις μαθηματικές πράξεις συνόλων. Οι περισσότερες (όχι όλες) από αυτές τις μεθόδους έχουν έναν ισοδύναμο τελεστή. Οι μέθοδοι γενικά δέχονται οποιοδήποτε iterable ως όρισμα, ενώ οι τελεστές απαιτούν και οι δύο πλευρές της πράξης να είναι sets ή frozensets.

Έλεγχος Συμμετοχής Μεταξύ Συνόλων

Η μέθοδος <set>.isdisjoint(<other_collection>) χρησιμοποιείται για να ελέγξει αν τα στοιχεία ενός set έχουν κάποια επικάλυψη με τα στοιχεία ενός άλλου. Η μέθοδος δέχεται οποιοδήποτε iterable ή set ως όρισμα. Θα επιστρέψει True αν τα δύο σύνολα δεν έχουν κοινά στοιχεία, False αν τα στοιχεία είναι κοινά.

# Both mammals and additional_animals are lists.
>>> mammals = ['squirrel','dog','cat','cow', 'tiger', 'elephant']
>>> additional_animals = ['pangolin', 'panda', 'parrot', 
                          'lemur', 'tiger', 'pangolin']

# Animals is a dict.
>>> animals = {'chicken': 'white',
               'sparrow': 'grey',
               'eagle': 'brown and white',
               'albatross': 'grey and white',
               'crow': 'black',
               'elephant': 'grey', 
               'dog': 'rust',
               'cow': 'black and white',
               'tiger': 'orange and black',
               'cat': 'grey',
               'squirrel': 'black'}
               
# Birds is a set.
>>> birds = {'crow','sparrow','eagle','chicken', 'albatross'}

# Mammals and birds don't share any elements.
>>> birds.isdisjoint(mammals)
True

# There are also no shared elements between 
# additional_animals and birds.
>>> birds.isdisjoint(additional_animals)
True

# Animals and mammals have shared elements.
# **Note** The first object needs to be a set or converted to a set
# since .isdisjoint() is a set method.
>>> set(animals).isdisjoint(mammals)
False

Έλεγχος για Υποσύνολα και Υπερσύνολα

Το <set>.issubset(<other_collection>) χρησιμοποιείται για να ελέγξει αν κάθε στοιχείο του <set> βρίσκεται και στο <other_collection>. Η μορφή με τελεστή είναι <set> <= <other_set>:

# Set methods will take any iterable as an argument.
# All members of birds are also members of animals.
>>> birds.issubset(animals)
True

# All members of mammals also appear in animals.
# **Note** The first object needs to be a set or converted to a set
# since .issubset() is a set method.
>>> set(mammals).issubset(animals)
True

# Both objects need to be sets to use a set operator
>>> birds <= set(mammals)
False

# A set is always a loose subset of itself.
>>> set(additional_animals) <= set(additional_animals)
True

Το <set>.issuperset(<other_collection>) είναι το αντίστροφο του .issubset(). Χρησιμοποιείται για να ελέγξει αν κάθε στοιχείο του <other_collection> βρίσκεται και στο <set>. Η μορφή με τελεστή είναι <set> >= <other_set>:

# All members of mammals also appear in animals.
# **Note** The first object needs to be a set or converted to a set
# since .issuperset() is a set method.
>>> set(animals).issuperset(mammals)
True

# All members of animals do not show up as members of birds.
>>> birds.issuperset(animals)
False

# Both objects need to be sets to use a set operator
>>> birds >= set(mammals)
False

# A set is always a loose superset of itself.
>>> set(animals) >= set(animals)
True

"Γνήσια" Υποσύνολα και Υπερσύνολα

Τα <set> < <other_set> και <set> > <other_set> χρησιμοποιούνται για να ελέγξουν για γνήσια υποσύνολα. Ένα set είναι γνήσιο υποσύνολο αν (<set> <= <other_set>) ΚΑΙ (<set> != <other_set>) για τον τελεστή <.

Ένα set είναι γνήσιο υπερσύνολο αν (<set> >= <other_set>) ΚΑΙ (<set> != <other_set>) για τον τελεστή >. Αυτοί οι τελεστές δεν έχουν αντίστοιχη μέθοδο:

>>> animal_names = {'albatross','cat','chicken','cow','crow','dog',
                   'eagle','elephant','sparrow','squirrel','tiger'}

>>> animals_also = {'albatross','cat','chicken','cow','crow','dog',
                   'eagle','elephant','sparrow','squirrel','tiger'}

>>> mammals = {'squirrel','dog','cat','cow', 'tiger', 'elephant'}
>>> birds   = {'crow','sparrow','eagle','chicken', 'albatross'}

>>> mammals < animal_names
True

>>> animal_names > birds
True

# A set is not a *proper subset* if set == other set.
>>> animals_also < animal_names
False

# A set is never a *proper subset* of itself
>>> animals_also < animals_also
False

Ενώσεις Συνόλων

Το <set>.union(*<other iterables>) επιστρέφει ένα νέο set με στοιχεία από το <set> και όλα τα <other iterables>. Η μορφή με τελεστή αυτής της μεθόδου είναι <set> | <other set 1> | <other set 2> | ... | <other set n>.

>>> perennials = {'Asparagus', 'Broccoli', 'Sweet Potato', 'Kale'}
>>> annuals = {'Corn', 'Zucchini', 'Sweet Peas', 'Summer Squash'}
>>> more_perennials = ['Radicchio', 'Rhubarb', 
                      'Spinach', 'Watercress']

# Methods will take any iterable as an argument.
>>> perennials.union(more_perennials)
{'Asparagus','Broccoli','Kale','Radicchio','Rhubarb',
'Spinach','Sweet Potato','Watercress'}

# Operators require sets.
>>> set(more_perennials) | perennials
{'Asparagus',
 'Broccoli',
 'Kale',
 'Radicchio',
 'Rhubarb',
 'Spinach',
 'Sweet Potato',
 'Watercress'}

Διαφορές Συνόλων

Το <set>.difference(*<other iterables>) επιστρέφει ένα νέο set με στοιχεία από το αρχικό <set> που δεν βρίσκονται στα <others>. Η έκδοση με τελεστή αυτής της μεθόδου είναι <set> - <other set 1> - <other set 2> - ... - <other set n>.

>>> berries_and_veggies = {'Asparagus', 
                          'Broccoli', 
                          'Watercress', 
                          'Goji Berries', 
                          'Goose Berries', 
                          'Ramps', 
                          'Walking Onions', 
                          'Blackberries', 
                          'Strawberries', 
                          'Rhubarb', 
                          'Kale', 
                          'Artichokes', 
                          'Currants'}

>>> veggies = ('Asparagus', 'Broccoli', 'Watercress', 'Ramps',
               'Walking Onions', 'Rhubarb', 'Kale', 'Artichokes')

# Methods will take any iterable as an argument.
>>> berries = berries_and_veggies.difference(veggies)
{'Blackberries','Currants','Goji Berries',
 'Goose Berries', 'Strawberries'}

# Operators require sets.
>>> berries_and_veggies - berries
{'Artichokes','Asparagus','Broccoli','Kale',
'Ramps','Rhubarb','Walking Onions','Watercress'}

Τομές Συνόλων

Το <set>.intersection(*<other iterables>) επιστρέφει ένα νέο set με στοιχεία κοινά στο αρχικό set και σε όλα τα <others> (με άλλα λόγια, το set όπου όλα τέμνονται). Η έκδοση με τελεστή αυτής της μεθόδου είναι <set> & <other set> & <other set 2> & ... & <other set n>

>>> perennials = {'Annatto','Asafetida','Asparagus','Azalea',
                 'Winter Savory', 'Broccoli','Curry Leaf','Fennel', 
                 'Kaffir Lime','Kale','Lavender','Mint','Oranges',
                 'Oregano', 'Tarragon', 'Wild Bergamot'}

>>> annuals = {'Corn', 'Zucchini', 'Sweet Peas', 'Marjoram', 
              'Summer Squash', 'Okra','Shallots', 'Basil', 
              'Cilantro', 'Cumin', 'Sunflower', 'Chervil', 
              'Summer Savory'}

>>> herbs = ['Annatto','Asafetida','Basil','Chervil','Cilantro',
            'Curry Leaf','Fennel','Kaffir Lime','Lavender',
            'Marjoram','Mint','Oregano','Summer Savory', 
            'Tarragon','Wild Bergamot','Wild Celery',
            'Winter Savory']


# Methods will take any iterable as an argument.
>>> perennial_herbs = perennials.intersection(herbs)
{'Annatto', 'Asafetida', 'Curry Leaf', 'Fennel', 'Kaffir Lime',
 'Lavender', 'Mint', 'Oregano', 'Wild Bergamot','Winter Savory'}

# Operators require both groups be sets.
>>> annuals & set(herbs)
 {'Basil', 'Chervil', 'Marjoram', 'Cilantro'}

Συμμετρικές Διαφορές Συνόλων

Το <set>.symmetric_difference(<other iterable>) επιστρέφει ένα νέο set που περιέχει στοιχεία που βρίσκονται στο <set> Ή στο <other>, αλλά όχι και στα δύο. Η έκδοση με τελεστή αυτής της μεθόδου είναι <set> ^ <other set>.

>>> plants_1 = {'🌲','🍈','🌵', '🥑','🌴', '🥭'}
>>> plants_2 = ('🌸','🌴', '🌺', '🌲', '🌻', '🌵')


# Methods will take any iterable as an argument.
>>> fruit_and_flowers = plants_1.symmetric_difference(plants_2)
>>> fruit_and_flowers
{'🌸', '🌺', '🍈', '🥑', '🥭','🌻' }


# Operators require both groups be sets.
>>> fruit_and_flowers ^ plants_1
{'🌲',  '🌸', '🌴', '🌵','🌺', '🌻'}

>>> fruit_and_flowers ^ set(plants_2)
{'🥭', '🌴', '🌵', '🍈', '🌲', '🥑'}
Note

Μια συμμετρική διαφορά περισσότερων από δύο συνόλων θα έχει ως αποτέλεσμα ένα set που περιλαμβάνει και τα στοιχεία που είναι μοναδικά σε κάθε set ΚΑΙ τα στοιχεία που μοιράζονται μεταξύ περισσότερων από δύο συνόλων στη σειρά (λεπτομέρειες στο άρθρο της Wikipedia για τη συμμετρική διαφορά).

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

>>> one = {'black pepper','breadcrumbs','celeriac','chickpea flour',
           'flour','lemon','parsley','salt','soy sauce',
           'sunflower oil','water'}

>>> two = {'black pepper','cornstarch','garlic','ginger',
           'lemon juice','lemon zest','salt','soy sauce','sugar',
           'tofu','vegetable oil','vegetable stock','water'}

>>> three = {'black pepper','garlic','lemon juice','mixed herbs',
             'nutritional yeast', 'olive oil','salt','silken tofu',
             'smoked tofu','soy sauce','spaghetti','turmeric'}

>>> four = {'barley malt','bell pepper','cashews','flour',
            'fresh basil','garlic','garlic powder', 'honey',
            'mushrooms','nutritional yeast','olive oil','oregano',
            'red onion', 'red pepper flakes','rosemary','salt',
            'sugar','tomatoes','water','yeast'}

>>> intersections = (one & two | one & three | one & four | 
                     two & three | two & four | three & four)
...
{'black pepper','flour','garlic','lemon juice','nutritional yeast', 
'olive oil','salt','soy sauce', 'sugar','water'}

# The ^ operation will include some of the items in intersections, 
# which means it is not a "clean" symmetric difference - there
# are overlapping members.
>>> (one ^ two ^ three ^ four) & intersections
{'black pepper', 'garlic', 'soy sauce', 'water'}

# Overlapping members need to be removed in a separate step
# when there are more than two sets that need symmetric difference.
>>> (one ^ two ^ three ^ four) - intersections
...
{'barley malt','bell pepper','breadcrumbs', 'cashews','celeriac',
  'chickpea flour','cornstarch','fresh basil', 'garlic powder',
  'ginger','honey','lemon','lemon zest','mixed herbs','mushrooms',
  'oregano','parsley','red onion','red pepper flakes','rosemary',
  'silken tofu','smoked tofu','spaghetti','sunflower oil', 'tofu', 
  'tomatoes','turmeric','vegetable oil','vegetable stock','yeast'}
Επεξεργασία μέσω GitHub Ο σύνδεσμος ανοίγει σε νέο παράθυρο ή καρτέλα

Μάθε την έννοια Σύνολα

Η εξάσκηση είναι κλειδωμένη

Ξεκλείδωσε 4 ακόμη ασκήσεις για να εξασκηθείς στην έννοια Σύνολα