*Memo:
- My post explains set functions (1).
- My post explains set functions (2).
- My post explains the shallow copy of the set with a tuple.
- My post explains the shallow and deep copy of the set with an iterator.
- My post explains a list and the list with indexing.
- My post explains a tuple.
- My post explains a dictionary (1).
- My post explains an iterator (1).
- My post explains a string.
- My post explains a bytes.
- My post explains a bytearray.
A set:
- is the unordered collection of zero or more elements whose type is
set
:- Unordered means that the order of the elements in a set isn't kept so it doesn't guarantee that the order is always the same.
- shouldn't be huge not to get
MemoryError
. - doesn't allow duplicated elements (even with different types).
- is mutable so it can be changed:
- can have the hashable types of elements:
- A hashable type is the type whose value cannot be changed like
str
,bytes
,int
,float
,complex
,bool
,tuple
,frozenset
,range
oriterator
.
- A hashable type is the type whose value cannot be changed like
- cannot have the unhashable types of elements:
- A unhashable type is the type whose value can be changed like
bytearray
,list
,set
ordict
.
- A unhashable type is the type whose value can be changed like
- can be iterated with a
for
statement. - can be unpacked with an assignment and
for
statement, function and*
but not with**
. - is
False
if it's empty. - can be checked if a specific element is or isn't in it with
in
keyword ornot
andin
keyword respectively. - can be checked if it is or isn't referred to by two variables with
is
keyword ornot
andis
keyword respectively. - cannot be enlarged with
*
and a number. - can be created by
{}
, set() with or without an iterable or a set comprehension:- For
set()
, the words type conversion are also suitable in addition to the word creation.
- For
- cannot be read or changed by indexing or slicing.
- can be continuously used through multiple variables.
- can be copied to refer to a different set.
A set is for non-huge data otherwise it gets MemoryError
.
{}
can create a set as shown below:
*Memo:
- Be careful, the empty curlybraces
{}
are an empty dictionary but not an empty set so use set() to create an empty set.
A = set() # Empty 1D set.
A = {} # dict not set.
A = {10, 20, 30, 40, 50, 60} # 1D set
A = {10, 20, 30, 10, 20, 30} # 1D set
A = {10, 20, frozenset({10, 20, 10, 20})} # 2D set
A = {10, 20, frozenset({10, 20, frozenset({10, 20})})} # 3D set
# No error
A = {1, 1.0, 1.0+0.0j, True}
A = {'A', b'A', 2, 2.3, 2.3+4.5j, True, (2, 3), frozenset({2, 3}),
range(2, 3), iter([2, 3])}
for v in {0, 1, 2}: pass
v1, v2, v3 = {0, 1, 2}
v1, *v2, v3 = {0, 1, 2, 3, 4, 5}
for v1, v2, v3 in {frozenset({0, 1, 2}), frozenset({3, 4, 5})}: pass
for v1, *v2, v3 in {frozenset({0, 1, 2, 3, 4, 5}),
frozenset({6, 7, 8, 9, 10, 11})}: pass
print({*{0, 1, *{2}}, *{3, 4}})
print(*{0, 1, *{2}}, *{3, 4})
A = {x**2 for x in range(6)}
# No error
A = {10, 20, [30, 40], 50, 60}
A = {10, 20, {30, 40}, 50, 60}
A = {10, 20, {30:40, 50:60}, 70, 80}
A = {bytearray(b'Hello')}
print(**{0, 1, 2, 3, 4})
A = {10, 20, 30} * 3
# Error
A set is the unordered collection of zero or more elements whose type is set
as shown below:
A = {10, 20, 30, 40, 50, 60}
print(A)
# {50, 20, 40, 10, 60, 30}
print(type(A))
# <class 'set'>
A = set() # Empty set
print(A)
# set()
A set doesn't allow duplicated elements (even with different types) as shown below:
A = {10, 20, 30, 10, 20, 30}
print(A)
# {10, 20, 30}
A = {1, 1.0, 1.0+0.0j, True}
print(A)
# {1}
A = {10, 20, frozenset({10, 20, 10, 20})}
print(A)
# {10, 20, frozenset({10, 20})}
A = {10, 20, frozenset({10, 20, frozenset({10, 20})})}
print(A)
# {10, 20, frozenset({10, 20, frozenset({10, 20})})}
A set can have the hashable types of elements as shown below:
A = {'A', b'A', 2, 2.3, 2.3+4.5j, True, (2, 3), frozenset({2, 3}),
range(2, 3), iter([2, 3])}
print(A)
# {True, 2, 2.3, frozenset({2, 3}),
# <list_iterator object at 0x000001F3B9E5F250>,
# b'A', (2.3+4.5j), (2, 3), 'A', range(2, 3)}
A set cannot have the unhashable types of elements as shown below:
A = {10, 20, [30, 40], 50, 60} # set(list)
# TypeError: unhashable type: 'list'
A = {10, 20, {30, 40}, 50, 60} # set(set)
# TypeError: unhashable type: 'set'
A = {10, 20, {30:40, 50:60}, 70, 80} # set(dict)
# TypeError: unhashable type: 'dict'
A = {bytearray(b'Hello')} # set(bytearray)
# TypeError: unhashable type: 'bytearray'
A set can be iterated with a for
statement as shown below:
for v in {0, 1, 2}:
print(v)
# 0
# 1
# 2
A set can be unpacked with an assignment and for
statement, function and *
but not with **
as shown below:
v1, v2, v3 = {0, 1, 2}
print(v1, v2, v3)
# 0 1 2
v1, *v2, v3 = {0, 1, 2, 3, 4, 5}
print(v1, v2, v3) # 0 [1, 2, 3, 4] 5
print(v1, *v2, v3) # 0 1 2 3 4 5
for v1, v2, v3 in {frozenset({0, 1, 2}),
frozenset({3, 4, 5})}:
print(v1, v2, v3)
# 3 4 5
# 0 1 2
for v1, *v2, v3 in {frozenset({0, 1, 2, 3, 4, 5}),
frozenset({6, 7, 8, 9, 10, 11})}:
print(v1, v2, v3)
print(v1, *v2, v3)
# 6 [7, 8, 9, 10] 11
# 6 7 8 9 10 11
# 0 [1, 2, 3, 4] 5
# 0 1 2 3 4 5
def func(p1='a', p2='b', p3='c', p4='d', p5='e', p6='f'):
print(p1, p2, p3, p4, p5, p6)
func()
# a b c d e f
func(*{0, 1, 2, 3}, *{4, 5})
# 0 1 2 3 4 5
def func(p1='a', p2='b', *args):
print(p1, p2, args)
print(p1, p2, *args)
print(p1, p2, ['A', 'B', *args, 'C', 'D'])
func()
# a b ()
# a b Nothing
# a b ['A', 'B', 'C', 'D']
func(*{0, 1, 2, 3}, *{4, 5})
# 0 1 (2, 3, 4, 5)
# 0 1 2 3 4 5
# 0 1 ['A', 'B', 2, 3, 4, 5, 'C', 'D']
print({*{0, 1, *{2}}, *{3, 4}})
# {0, 1, 2, 3, 4}
print(*{0, 1, *{2}}, *{3, 4})
# 0 1 2 3 4
print(**{0, 1, 2, 3, 4})
# TypeError: print() argument after ** must be a mapping, not set
An empty set is False
as shown below:
print(bool(set())) # Empty set
# False
print(bool({0})) # set
print(bool({frozenset()})) # set(Empty frozenset)
# True
A set can be checked if a specific element is or isn't in it with in
keyword or not
and in
keyword respectively as shown below:
v = {10, 20, frozenset({30, 40})}
print(20 in v)
# True
print({30, 40} in v)
# True
print(2 in v)
# False
v = {10, 20, frozenset({30, 40})}
print(20 not in v)
# False
print({30, 40} not in v)
# False
print(2 not in v)
# True
A set cannot be enlarged with *
and a number as shown below:
A = {10, 20, 30} * 3
# TypeError: unsupported operand type(s) for *: 'set' and 'int'
set()
can create a set with or without an iterable as shown below:
*Memo:
- The 1st argument is
iterable
(Optional-Default:()
-Type:Iterable):- Don't use
iterable=
.
- Don't use
# Empty set
print(set())
print(set(()))
# set()
print(set([0, 1, 2, 3, 4])) # list
print(set((0, 1, 2, 3, 4))) # tuple
print(set(iter([0, 1, 2, 3, 4]))) # iterator
print(set({0, 1, 2, 3, 4})) # set
print(set(frozenset({0, 1, 2, 3, 4}) )) # frozenset
print(set(range(5))) # range
# {0, 1, 2, 3, 4}
print(set({'name': 'John', 'age': 36})) # dict
print(set({'name': 'John', 'age': 36}.keys())) # dict.keys()
# {'age', 'name'}
print(set({'name': 'John', 'age': 36}.values())) # dict.values()
# {'John', 36}
print(set({'name': 'John', 'age': 36}.items())) # dict.items()
# {('age', 36), ('name', 'John')}
print(set('Hello')) # str
# {'H', 'e', 'l', 'o'}
print(set(b'Hello')) # bytes
print(set(bytearray(b'Hello'))) # bytearray
# {72, 108, 101, 111}
A set comprehension can create a set as shown below:
A = {x**2 for x in range(6)}
print(A)
# {0, 1, 4, 9, 16, 25}
Be careful, a huge set gets MemoryError
as shown below:
A = range(100000000)
print(set(v))
# MemoryError
A set cannot be read or changed by indexing or slicing as shown below:
*Memo:
- A del statement can still be used to remove one or more variables themselves.
A = {10, 20, 30, 40, 50, 60}
print(A[0], A[2:6])
# TypeError: 'set' object is not subscriptable
A = {10, 20, 30, 40, 50, 60}
A[0] = 100
A[2:6] = [200, 300]
# TypeError: 'set' object does not support item assignment
A = {10, 20, 30, 40, 50, 60}
del A[0], A[3:5]
# TypeError: 'set' object doesn't support item deletion
A = {10, 20, 30, 40, 50, 60}
del A
print(A)
# NameError: name 'A' is not defined
If you really want to read or change a tuple, use list() and set()
as shown below:
A = {10, 20, 30, 40, 50, 60}
A = list(A)
print(A[0], A[2:6])
# 50 [40, 10, 60, 30]
A[0] = 100
A[2:6] = [200, 300]
A = set(A)
print(A)
# {200, 100, 20, 300}
A = {10, 20, 30, 40, 50, 60}
A = list(A)
del A[0], A[3:5]
A = set(A)
print(A)
# {40, 10, 20}
A set can be continuously used through multiple variables as shown below:
A = B = C = {10, 20, 30} # Equivalent
# v1 = {10, 20, 30}
A.update({40, 50}) # v2 = v1
B.remove(30) # v3 = v2
C.pop()
print(A) # {20, 40, 10}
print(B) # {20, 40, 10}
print(C) # {20, 40, 10}
The variables A
and B
refer to the same set unless copied as shown below:
*Memo:
-
is
keyword oris
andnot
keyword can check ifA
andB
refer or don't refer to the same set respectively. -
set.copy(), copy.copy() and
set()
do shallow copy:-
set.copy()
has no arguments.
-
- copy.deepcopy() does deep copy.
-
copy.deepcopy()
should be used because it's safe, doing copy deeply whileset.copy()
,copy.copy()
andset()
aren't safe, doing copy shallowly.
import copy
A = {10, 20, 30}
B = A # B refers to the same set as A.
B.add(40) # Changes the same set as A.
# ↓↓
print(A) # {40, 10, 20, 30}
print(B) # {40, 10, 20, 30}
# ↑↑
print(A is B, A is not B)
# True False
# B refers to the different set from A.
B = A.copy()
B = copy.copy(A)
B = copy.deepcopy(A)
B = set(A)
B.add(50) # Changes a different set from A.
print(A) # {40, 10, 20, 30}
print(B) # {40, 10, 50, 20, 30}
# ↑↑
print(A is B, A is not B)
# False True
Top comments (0)