5.3. Unpack Assignment¶
a = 1
- Assignmenta, b = 1, 2
- Unpacking assignmenta = b = 1
- Chained assignment_
is regular variable name, not a special Python syntax_
by convention is used for data we don't want to access in future
Assignment:
>>> a = 1
Unpacking assignment:
>>> a, b = 1, 2
Chained assignment:
>>> a = b = 1
Chained unpacking assignment:
>>> a, b = c, d = 1, 2
5.3.1. Example¶
>>> def get_user_details(username):
... return 'Mark', 'Watney', 'mwatney@nasa.gov'
>>>
>>>
>>> firstname, lastname, email = get_user_details('mwatney')
>>>
>>> firstname
'Mark'
>>>
>>> lastname
'Watney'
>>>
>>> email
'mwatney@nasa.gov'
5.3.2. Assignment¶
Scalar Assignment
identifier = object
a = 1
a = 1, 2
>>> a = 1
>>>
>>> print(f'{a=}')
a=1
>>> a = 1, 2
>>>
>>> print(f'{a=}')
a=(1, 2)
5.3.3. Unpacking Assignment¶
iterable[identifier] = iterable[object]
a, b = 1, 2
a, b, c = 1, 2, 3
Sequence -> tuple, list
Iterable -> tuple, list, set, frozenset, dict, ...
Length at right and left side must be the same
>>> a, b = 1, 2
>>>
>>> print(f'{a=}, {b=}')
a=1, b=2
>>> a, = 1,
>>> a, b = 1, 2
>>> a, b, c = 1, 2, 3
>>> a, b, c, d = 1, 2, 3, 4
>>> a, b, c, d, e = 1, 2, 3, 4, 5
>>> a, b, c = 1, 2
Traceback (most recent call last):
ValueError: not enough values to unpack (expected 3, got 2)
>>> a, b, c = 1, 2, 3, 4
Traceback (most recent call last):
ValueError: too many values to unpack (expected 3)
5.3.4. Chained Assignment¶
identifier1 = identifier2 = object
a = b = 1
a = b = c = 1
>>> a = b = 1
>>>
>>> print(f'{a=}, {b=}')
a=1, b=1
>>> a = b = 1
>>> a = b = c = 1
>>> a = b = c = d = 1
>>> a = b = c = d = e = 1
5.3.5. Chained Unpacking Assignment¶
iterable[identifier] = iterable[identifier] = iterable[object]
>>> a, b = c, d = 1, 2
>>>
>>> print(f'{a=}, {b=}, {c=}, {d=}')
a=1, b=2, c=1, d=2
>>> a = b, c = 1, 2
>>>
>>> print(f'{a=}, {b=}, {c=}')
a=(1, 2), b=1, c=2
5.3.6. Brackets¶
Brackets does not define tuple, commas do:
>>> a = 1, 2, 3
>>> b = (1, 2, 3)
>>>
>>> a == b
True
>>> a = (1, 2)
>>> type(a)
<class 'tuple'>
>>>
>>> a = 1, 2
>>> type(a)
<class 'tuple'>
>>> 1+2 * 3
7
>>>
>>> (1+2) * 3
9
>>>
>>> (1+2,) * 3
(3, 3, 3)
Right-Side Brackets:
>>> a, b, c = 1, 2, 3
>>> a, b, c = (1, 2, 3)
>>> a, b, c = [1, 2, 3]
>>> a, b, c = {1, 2, 3}
Left-Side Brackets:
>>> (a, b, c) = 1, 2, 3
>>> [a, b, c] = 1, 2, 3
>>> {a, b, c} = 1, 2, 3
Traceback (most recent call last):
SyntaxError: cannot assign to set display here. Maybe you meant '==' instead of '='?
Warning:
>>> (a) = 1
>>> (a,) = 1,
Errors:
>>> (a,) = 1
Traceback (most recent call last):
TypeError: cannot unpack non-iterable int object
>>> [a] = 1
Traceback (most recent call last):
TypeError: cannot unpack non-iterable int object
5.3.7. Swap¶
Swap two variables
>>> a = 1
>>> b = 2
>>>
>>> a, b = b, a
>>>
>>> a
2
>>> b
1
5.3.8. Unpacking¶
>>> data = ['Mark', 'Watney', 'mwatney@nasa.gov']
>>> firstname, lastname, email = data
>>>
>>> print(firstname)
Mark
>>>
>>> print(lastname)
Watney
>>>
>>> print(email)
mwatney@nasa.gov
5.3.9. Nested¶
>>> data = ['Mark', 'Watney', ('mwatney@nasa.gov', 'mwatney@gmail.com')]
>>> firstname, lastname, emails = data
>>> print(emails)
('mwatney@nasa.gov', 'mwatney@gmail.com')
>>> firstname, lastname, (email_work, email_home) = data
>>>
>>> print(email_work)
mwatney@nasa.gov
>>>
>>> print(email_home)
mwatney@gmail.com
5.3.10. Skipping Values¶
_
is regular variable name, not a special Python syntax_
by convention is used for data we don't want to access in future
>>> _ = 'Mark Watney'
>>>
>>> print(_)
Mark Watney
>>> data = ['Mark', 'Watney', 'mwatney@nasa.gov']
>>>
>>> firstname, lastname, email = data
>>> firstname, lastname, _ = data
>>> firstname, _, _ = data
>>> _, lastname, _ = data
>>> _, _, email = data
5.3.11. Copy Deep vs Reference¶
>>> a = b = 1
>>> a
1
>>> b
1
>>>
>>> a = 2
>>> a
2
>>> b
1
>>> a = b = [1, 2]
>>>
>>> a
[1, 2]
>>> b
[1, 2]
>>>
>>> a.append(3)
>>>
>>> a
[1, 2, 3]
>>> b
[1, 2, 3]
5.3.12. Use Case - 0x01¶
>>> a, b, c = range(0, 3)
>>> a, b, c, d, e = range(0, 5)
>>> a, b, c, d, e, f, g, h, i, j = range(0, 10)
5.3.13. Use Case - 0x02¶
>>> import sys
>>>
>>> major, minor, patch, *_ = sys.version_info
>>>
>>>
>>> print(major)
3
>>>
>>> print(minor)
11
5.3.14. Use Case - 0x03¶
>>> line = '5.1,3.5,1.4,0.2,setosa'
>>> sl, sw, pl, pw, species = line.split(',')
>>>
>>>
>>> sl
'5.1'
>>>
>>> sw
'3.5'
>>>
>>> pl
'1.4'
>>>
>>> pw
'0.2'
>>>
>>> species
'setosa'
5.3.15. Use Case - 0x04¶
Line from
/etc/passwd
>>> line = 'watney:x:1000:1000:Mark Watney:/home/watney:/bin/bash'
>>> username, _, uid, _, _, _, _ = line.split(':')
>>>
>>> print(f'{username=}, {uid=}')
username='watney', uid='1000'
5.3.16. Use Case - 0x05¶
>>> log = '1969-07-21, 02:56:15, WARNING, Neil Armstrong first words on the Moon'
>>> date, time, level, message = log.split(', ')
>>>
>>>
>>> date
'1969-07-21'
>>>
>>> time
'02:56:15'
>>>
>>> level
'WARNING'
>>>
>>> message
'Neil Armstrong first words on the Moon'
5.3.17. Use Case - 0x06¶
Skip
>>> a, b, _ = 'red', 'green', 'blue'
>>> a, _, _ = 'red', 'green', 'blue'
>>> a, _, c = 'red', 'green', 'blue'
>>> _, b, _ = 'red', 'green', 'blue'
>>> _, _, c = 'red', 'green', 'blue'
5.3.18. Use Case - 0x07¶
Important
>>> _, important, _ = 1, 2, 3
>>>
>>> print(important)
2
>>> _, (important, _) = [1, (2, 3)]
>>>
>>> print(important)
2
>>> _, _, important = (True, [1, 2, 3, 4], 5)
>>>
>>> print(important)
5
>>> _, _, important = (True, [1, 2, 3, 4], (5, True))
>>>
>>> print(important)
(5, True)
>>>
>>> _, _, (important, _) = (True, [1, 2, 3, 4], (5, True))
>>>
>>> print(important)
5
Python understands this as:
>>> _ = (True, [1, 2, 3, 4], (5, True))
>>>
>>> a,b,c = (object, object, object)
>>> a,b,(c,d) = (object, object, (object,object))
5.3.19. Use Case - 0x08¶
>>> row = (5.8, 2.7, 5.1, 1.9, 'virginica')
>>> sl = row[0]
>>> sw = row[1]
>>> pl = row[2]
>>> pw = row[3]
>>> species = row[4]
>>>
>>> print(f'{sl=}, {sw=}, {pl=}, {pw=}, {species=}')
sl=5.8, sw=2.7, pl=5.1, pw=1.9, species='virginica'
>>> sl, sw, pl, pw, species = row
>>>
>>> print(f'{sl=}, {sw=}, {pl=}, {pw=}, {species=}')
sl=5.8, sw=2.7, pl=5.1, pw=1.9, species='virginica'
5.3.20. Use Case - 0x09¶
>>> DATA = [
... (5.8, 2.7, 5.1, 1.9, 'virginica'),
... (5.1, 3.5, 1.4, 0.2, 'setosa'),
... (5.7, 2.8, 4.1, 1.3, 'versicolor'),
... ]
>>> for row in DATA:
... sl = row[0]
... sw = row[1]
... pl = row[2]
... pw = row[3]
... species = row[4]
... print(f'{sl=}, {sw=}, {pl=}, {pw=}, {species=}')
sl=5.8, sw=2.7, pl=5.1, pw=1.9, species='virginica'
sl=5.1, sw=3.5, pl=1.4, pw=0.2, species='setosa'
sl=5.7, sw=2.8, pl=4.1, pw=1.3, species='versicolor'
>>> for sl, sw, pl, pw, species in DATA:
... print(f'{sl=}, {sw=}, {pl=}, {pw=}, {species=}')
sl=5.8, sw=2.7, pl=5.1, pw=1.9, species='virginica'
sl=5.1, sw=3.5, pl=1.4, pw=0.2, species='setosa'
sl=5.7, sw=2.8, pl=4.1, pw=1.3, species='versicolor'
5.3.21. Recap¶
Four types of assignments: Scalar, Unpacking, Chained, Chained Unpacking Assignment
For unpacking assignment, lengths at both sides must be the same
Both left and right expression side brackets are optional
Unpacking nested sequences
Skipping values is done by using
_
Assignment:
>>> a = 1
Unpacking assignment:
>>> a, b = 1, 2
Chained assignment:
>>> a = b = 1
Chained unpacking assignment:
>>> a, b = c, d = 1, 2
Unpacking nested:
>>> a, (b, c) = 1, (2, 3)
Skipping:
>>> _, (important, _) = 1, (2, 3)
5.3.22. Assignments¶
"""
* Assignment: Unpack Assignment List
* Required: yes
* Complexity: easy
* Lines of code: 1 lines
* Time: 2 min
English:
1. Separate ip address and host name
2. Run doctests - all must succeed
Polish:
1. Odseparuj adres ip i nazwę hosta
2. Uruchom doctesty - wszystkie muszą się powieść
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> assert ip is not Ellipsis, \
'Assign your result to variable `ip`'
>>> assert host is not Ellipsis, \
'Assign your result to variable `host`'
>>> assert type(ip) is str, \
'Variable `ip` has invalid type, should be str'
>>> assert type(host) is str, \
'Variable `hosts` has invalid type, should be str'
>>> ip
'10.13.37.1'
>>> host
'nasa.gov'
"""
DATA = ['10.13.37.1', 'nasa.gov']
# IP address: 10.13.37.1
# type: str
ip = ...
# Host name: nasa.gov
# type: str
host = ...
"""
* Assignment: Unpack Assignment Split
* Required: yes
* Complexity: easy
* Lines of code: 1 lines
* Time: 2 min
English:
1. Split input data
2. Separate ip address and host name
3. Run doctests - all must succeed
Polish:
1. Podziel dane wejściowe
2. Odseparuj adres ip i nazwę hosta
3. Uruchom doctesty - wszystkie muszą się powieść
Hints:
* `str.split()`
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> assert ip is not Ellipsis, \
'Assign your result to variable `ip`'
>>> assert host is not Ellipsis, \
'Assign your result to variable `host`'
>>> assert type(ip) is str, \
'Variable `ip` has invalid type, should be str'
>>> assert type(host) is str, \
'Variable `hosts` has invalid type, should be str'
>>> ip
'10.13.37.1'
>>> host
'nasa.gov'
"""
DATA = '10.13.37.1 nasa.gov'
# IP address:
# example: 10.13.37.1
# type: str
ip = ...
# host name
# example: nasa.gov
# type: str
host = ...