Packing and Unpacking
def func1(x, y, z):
print x
print y
print z
def func2(*args):
# Convert args tuple to a list so we can modify it
args = list(args)
args[0] = 'Hello'
args[1] = 'awesome'
func1(*args)
func2('Goodbye', 'cruel', 'world!')
range(3, 6) # normal call with separate arguments
args = [3, 6]
range(*args) # call with arguments unpacked from a list
def parrot(voltage, state='a stiff', action='voom'):
print "-- This parrot wouldn't", action,
print "if you put", voltage, "volts through it.",
print "E's", state, "!"
d = {"state": "bleedin' demised", "action": "VOOM", "voltage": "four million"}
parrot(**d)
(2 * i + 1 for i in range(3))
a, b, c = (2 * i + 1 for i in range(3))
a, b,c
a, (b, c), d = [1, (2, 3), 4]
a
b
c
d
Swapping variables: an inside view
def bar(a, b, c, d):
d, c, b, a = a, b, c, d
import dis
dis.dis(bar)
def foo(a, b):
a, b = b, a
dis.dis(foo)
#https://hg.python.org/cpython/file/3696b9ae6b17/Python/peephole.c#l426
#/* Try to fold tuples of constants (includes a case for lists
#which are only used for "in" and "not in" tests).
#Skip over BUILD_SEQN 1 UNPACK_SEQN 1.
#Replace BUILD_SEQN 2 UNPACK_SEQN 2 with ROT2.
#Replace BUILD_SEQN 3 UNPACK_SEQN 3 with ROT3 ROT2. */
a, b = 1, 2 # simple sequence assignment
print(a, b)
a, b = ['green', 'blue'] # list asqignment
print (a, b)
a, b = 'XY' # string assignment
print (a, b)
a, b = range(1,5,2) # any iterable will do
print (a, b)
Nested sequence assignment
(a,b), c = "XY", "Z" # a = 'X', b = 'Y', c = 'Z'
print(a, b, c)
(a,b), c, = [1,2],'this' # a = '1', b = '2', c = 'this'
print(a, b, c)
(a,b), c = "XYZ" # ERROR -- too many values to unpack
(a,b), c = "XY" # ERROR -- need more than 1 value to unpack
(a,b), (c,) = [1,2],'this' # ERROR -- too many values to unpack
(a,b), c = "XY", "Z" # ERROR -- need more than 1 value to unpack
print(a, b, c)
a, b, c = "XY", "Z"
Extended sequence unpacking (Python 3) (switch to the other notebook)
*(a,*b), *c = 1,2,3,3,4,5,6,7
*(a,*b), c, d = 1,2,3,3,4,5,6,7
*(a,*b), (c, d) = 1,2,3,3,4,5,6,7
Negative indexing
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a[-1]
a[-3]
List slices (a[start:end])
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a[2:8]
List slices with negative indexing
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a[-4:-2]
List slices with step (a[start:end:step])
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a[::2]
a[::3]
a[2:8:2]
List slices with negative step
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a[::-1]
a[-2:]
a[:-2]
List slice assignment
a = [1, 2, 3, 4, 5]
a[2:3] = [0, 0]
a
a[1:1] = [8, 9]
a
a[1:-1] = []
a
Naming slices (slice(start, end, step))
a = [0, 1, 2, 3, 4, 5]
LASTTHREE = slice(-3, None)
LASTTHREE
a[LASTTHREE]
Iterating over list index and value pairs (enumerate)
a = ['Hello', 'world', '!']
for i, x in enumerate(a):
print '{}: {}'.format(i, x)
Iterating over dictionary key and value pairs (dict.iteritems) in Python 2
m = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
for k, v in m.iteritems():
print '{}: {}'.format(k, v)
Zipping and unzipping lists and iterables
a = [1, 2, 3]
b = ['a', 'b', 'c']
z = zip(a, b)
z
zip(*z)
zip([iterable, ...]) This function returns a list of tuples, where the i-th tuple contains the i-th element from each of the argument sequences or iterables. The returned list is truncated in length to the length of the shortest argument sequence. When there are multiple arguments which are all of the same length, zip() is similar to map() with an initial argument of None. With a single sequence argument, it returns a list of 1-tuples. With no arguments, it returns an empty list.
a = [1, 2, 3, 4] #Please note the 4 at the end
b = ['a', 'b', 'c']
z = zip(a, b)
z
items = [1, 2, 3, 4, 5]
def sqr(x): return x ** 2
map(sqr, items)
map(None, items)
a = [1, 2, 3]
b = ['a', 'b', 'c']
map(None, a, b)
map(None, a, b) == zip(a, b)
Grouping adjacent list items using zip
a = [1, 2, 3, 4, 5, 6]
# Using iterators
group_adjacent = lambda a, k: zip(*([iter(a)] * k))
group_adjacent(a, 3)