Um set é uma coleção mutável e não ordenada de objetos hashable.
Os elementos de um conjunto têm de ser distintos: não são permitidos itens duplicados.
Podem conter vários tipos de dados diferentes e até estruturas aninhadas, como um tuple de tuples, desde que seja possível calcular o hash de todos os elementos.
Os conjuntos também existem numa versão imutável frozenset.
Os conjuntos são habitualmente usados para remover rapidamente duplicados de outras estruturas de dados ou agrupamentos de itens. Também são usados para comparações eficientes quando não é preciso manter uma ordem nem controlar duplicados.
Tal como outros tipos de coleções (dicionários, listas, tuplas), os sets suportam:
for item in <set>,in e not in,len(), ecopy().Os sets não suportam:
+
Verificar a pertença num set tem complexidade temporal constante (em média), ao contrário de verificar a pertença numa list ou numa string, em que a complexidade temporal cresce à medida que o comprimento dos dados aumenta.
Métodos como <set>.union(), <set>.intersection() ou <set>.difference() também têm complexidade temporal constante (em média).
Embora os conjuntos possam ser criados de várias formas diferentes, os métodos de construção mais diretos são declarar um literal de conjunto, usar o construtor da classe set (set()) e usar uma compreensão de conjunto.
Um set pode ser escrito diretamente como um literal de conjunto, com chavetas {} e vírgulas entre os elementos.
Os duplicados são omitidos silenciosamente:
>>> one_element = {'➕'}
{'➕'}
>>> multiple_elements = {'➕', '🔻', '🔹', '🔆'}
{'➕', '🔻', '🔹', '🔆'}
>>> multiple_duplicates = {'Hello!', 'Hello!', 'Hello!',
'¡Hola!','Привіт!', 'こんにちは!',
'¡Hola!','Привіт!', 'こんにちは!'}
{'こんにちは!', '¡Hola!', 'Hello!', 'Привіт!'}
Os literais de conjunto usam as mesmas chavetas que os literais de dict, o que significa que tens de usar set() para criar um set vazio.
set() (o construtor da classe set) pode ser usado com qualquer iterable passado como argumento.
Os elementos do iterable são percorridos um a um e adicionados ao set individualmente.
A ordem dos elementos não é preservada e os duplicados são omitidos silenciosamente:
# 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}
Tal como lists e dicts, os conjuntos podem ser criados por compreensão:
# 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}
Devido ao seu comportamento de "desempacotamento", usar o construtor set com uma string pode ser surpreendente:
# 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('अभ्यास')
{'अ', 'भ', 'य', 'स', 'ा', '्'}
Lembra-te: os conjuntos podem conter tipos de dados diferentes e tipos de dados aninhados, mas todos os elementos de um set têm de ser 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'
No entanto, é possível criar um set de sets através do tipo 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({'☁️', '⭐️', '🌍'})}
Os elementos podem ser adicionados ou removidos de um set com os métodos <set>.add(<item>) e <set>.remove(<item>).
O método .remove(<item>) lança um KeyError se o item não estiver presente no 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>) remove um item do set, mas não lança um KeyError se o item não estiver presente.<set>.clear() remove todos os itens do conjunto.<set>.pop() remove e devolve um item arbitrário, e lança um KeyError se o set estiver vazio.Os conjuntos têm métodos que imitam, de um modo geral, as operações matemáticas de conjuntos.
A maioria (não todos) destes métodos tem um operador equivalente.
Os métodos aceitam, em geral, qualquer iterable como argumento, ao passo que os operadores exigem que ambos os lados da operação sejam sets ou frozensets.
O método <set>.isdisjoint(<other_collection>) serve para testar se os elementos de um set se sobrepõem, de alguma forma, aos elementos de outro.
O método aceita qualquer iterable ou set como argumento.
Devolve True se os dois conjuntos não tiverem elementos em comum e False se houver elementos partilhados.
# 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>) serve para verificar se todos os elementos de <set> também estão em <other_collection>.
A forma com operador é <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>) é o inverso de .issubset().
Serve para verificar se todos os elementos de <other_collection> também estão em <set>.
A forma com operador é <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> e <set> > <other_set> servem para testar subconjuntos próprios.
Um set é um subconjunto próprio se (<set> <= <other_set>) E (<set> != <other_set>) no caso do operador <.
Um set é um superconjunto próprio se (<set> >= <other_set>) E (<set> != <other_set>) no caso do operador >.
Estes operadores não têm um método equivalente:
>>> 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>) devolve um novo set com os elementos de <set> e de todos os <other iterables>.
A forma com operador deste método é <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>) devolve um novo set com os elementos do <set> original que não estão em <others>.
A versão com operador deste método é <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>) devolve um novo set com os elementos comuns ao set original e a todos os <others> (por outras palavras, o set onde tudo se interseta).
A versão com operador deste método é <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>) devolve um novo set com os elementos que estão em <set> OU em <other>, mas não em ambos.
A versão com operador deste método é <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)
{'🥭', '🌴', '🌵', '🍈', '🌲', '🥑'}
Uma diferença simétrica de mais de dois conjuntos origina um set que inclui tanto os elementos únicos de cada set COMO os elementos partilhados entre mais de dois conjuntos da série (mais detalhes no artigo da Wikipédia sobre diferença simétrica).
Para obter apenas os itens únicos de cada set da série, é preciso agregar num passo separado as interseções entre todas as combinações de dois conjuntos, e removê-las:
>>> 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'}