Python technique 1: sequence splitting

Time:2021-10-22

Any sequence (iteratable object) in Python can be split by assignment, including but not limited to tuples, lists, strings, files, iterators, generators, etc.

Tuple splitting

Tuple splitting is the most common splitting. Examples are as follows:

p = (4, 5)
x, y = p 
print(x, y) # 4 5

If written

x, y, z = p

Then a valueerror exception will be thrown: “not enough values to unpack (expected 3, got 2)”
If written

p = (4, 5, 6)
x, y = p

Then a valueerror exception will be thrown: “too many values to unpack (expected 2)”

String splitting

The splitting of strings is shown as follows:

s = 'Hello'
a, b, c, d, e = s
print(a) # H

Discard values when splitting

If you want to discard some specific values during splitting, you can use an unused variable name as the name of the discarded value (often choose ” as the variable name), as shown below:

s = 'Hello'
a, b, _, d, _ = s
print(a) # H

Nested sequence splitting

Python also provides a concise syntax for splitting nested sequences. We split a complex heterogeneous List as follows:

data = ['zhy', 50, 123.0, (2000, 12, 21)]
name, shares, price, (year, month, day) = data
print(year) # 2000

If you want to get (2000, 12, 21) the tuple representing the timestamp completely, you have to write as follows:

data = ['zhy', 50, 123.0, (2000, 12, 21)]
name, shares, price, date = data
print(date) # (2000, 12, 21)

Split from an iteratable object of any length

As we said before, if we want to decompose from iteratable objects\(N\)Elements, but if the length of this iteratable object exceeds\(N\), an exception “too many values to unpack” will be thrown. The solution to this problem is to use the “*” expression.
For example, when we give a student’s score, we want to remove the highest score and the lowest score, and then average the rest of the students. We can write as follows:

def avg(data: list):
    return sum(data)/len(data)
#Remove the highest score and the lowest score, and then make average statistics
def drop_first_last(grades):
    first, *middle, last = grades
    return avg(middle)
print(drop_first_last([1,2,3,4])) # 2.5

In another case, there are some user records, which are composed of name + e-mail + any number of phone numbers. We can decompose the user records as follows:

record = ['zhy', '[email protected]', '773-556234', '774-223333']
name, email, *phone_numbers = record
print(phone_numbers) # ['773-556234', '774-223333']

In fact, if the phone number is empty, it is also legal. At this time, the phone_ Numbers is an empty list.

record = ['zhy', '[email protected]']
name, email, *phone_numbers = record
print(phone_numbers) # []

Another use case is more ingenious. If we need to traverse a list of variable length tuples, these tuples have different lengths. Then the * expression can greatly simplify our code.

records = [('foo', 1, 2), ('bar', 'hello'), ('foo', 3, 4)]
for tag, *args in records:
    if tag == 'bar':
        print(args)
# ['hello']

The * expression is also particularly useful when splitting some complex strings.

line = "nobody:*:-2:-2:-2:Unprivileged User:/var/empty:/usr/bin/false"
uname, *fields, home_dir, sh = line.split(':')
print(home_dir) # /var/empty

*Expressions can also be used in conjunction with nested splitting and variable discarding.

record = ['ACME', 50, 123.45, (128, 18, 2012)]
name, *_, (*_, year) = record
print(year) # 2012

Finally, a dark magic of * expression for recursive functions is introduced. For example, in combination with recursive summation, it can be written as follows:

items = [1, 10, 7, 4, 5, 9]
def sum(items):
    head, *tail = items
    return head + sum(tail) if tail else head
print(sum(items)) # 36

However, Python is not good at recursion due to the limitation of its own recursion stack. Our last example of recursion can be used as an academic attempt, but it is not recommended to use it in practice.

reference

  • [1] Martelli A, Ravenscroft A, Ascher D. Python cookbook[M]. ” O’Reilly Media, Inc.”, 2005.

Recommended Today

Swift advanced (XV) extension

The extension in swift is somewhat similar to the category in OC Extension can beenumeration、structural morphology、class、agreementAdd new features□ you can add methods, calculation attributes, subscripts, (convenient) initializers, nested types, protocols, etc What extensions can’t do:□ original functions cannot be overwritten□ you cannot add storage attributes or add attribute observers to existing attributes□ cannot add parent […]