Sunday, January 5, 2025

Using * (args, kwargs, upacking, etc.) in Python

Everything * Can Be Used For In Python (Aside From Basic Math)

https://levelup.gitconnected.com/everything-can-be-used-for-in-python-aside-from-basic-math-a1c52426fc85


1) *args in Function Parameters

We can add *args in our function parameters to enable our function to take in any number of positional arguments. The * before args indicates that it will collect any number of positional arguments into a single variable. Inside the function, args is treated as a tuple.

def hello(*args):

  print(args)

hello()

hello(1)

hello(1, 2)

hello(1, 2, 3)


def hello(a, b, *args):

  print(args)

hello(1, 2)

hello(1, 2, 3)

=========================================================================

2) **kwargs in Function Parameters

Using ** instead of * allows us to take in any number of keyword arguments. Inside the function, kargs is treated as a dictionary, which stores key-value pairs.

def hello(**kargs):

  print(kargs)

hello()

hello(a=1)

hello(a=1, b=2)


def hello(a, b, **kwargs):

  print(kwargs)

hello(a=1, b=2)

hello(a=1, b=2, c=3)

=========================================================================

3) *args in Function Arguments

We can also use * to unpack an iterable into our function arguments.

L = [1, 2]

print(*L)


D = {1:'a', 2:'b'}

print(*D)


def hi(a, b, c):

  print(f"{a=} {b=} {c=}")

hi(1, 2, 3)

L = [4, 5, 6]

hi(*L)


def hi(a, b, c):

  print(f"{a=} {b=} {c=}")

hi(1, 2, 3)

=========================================================================

4) **kwargs in Function Arguments

If we use ** instead of *, we can do the same with dictionaries. Here, hi(**mydict) is the same as hi(a=4, b=5, c=6)

def hi(a, b, c):

  print(f"{a=}, {b=}, {c=}")

hi(a=4, b=5, c=6)

D = {'a':4, 'b':5, 'c':6}

hi(**D)

Similarly, we can also combine normal keyword arguments with **mydict as long as we pass all required keyword arguments into our function.

def hi(a, b, c):

  print(f"{a=}, {b=}, {c=}")

D = {'a':4, 'b':5, 'c':6}

hi(**D)

D = {'b':5, 'c':6}

hi(a=4, **D)

=========================================================================

5) Any parameter after * must be a keyword argument.

* is not placed before any parameter — this means that any parameter defined after * must be a keyword argument. In this case, c & d come after *, so c & d can only be keyword arguments. a & b can be positional or keyword arguments, but c & d must be keyword arguments. 

def hello(a, b, *, c, d):

  print(a, b, c, d)

hello(1, 2, c=3, d=4)

hello(a=1, b=2, c=3, d=4)

If we replace * alone with a / alone, this means that any function parameter defined before the / must be a positional argument.

def hello(a, b, /, c, d):

  print(a, b, c, d)

hello(1, 2, c=3, d=4)

hello(1, 2, 3, 4)

We can combine these to force additional restrictions on our function parameters.

def hola(a, b, /, c, d, *, e, f):

  print(a, b, c, d, e, f)

hola(1, 2, 3, d=4, e=5, f=6)

=========================================================================

6) *args in tuple unpacking

We can use tuple unpacking to elegantly assign multiple variables at once.

person = ['bob', 'M', 20]

name, gender, age = person

print(name, gender, age)

We can combine tuple unpacking with * if we have unused variables. If we have many more fields in person, but we only need the first 2 for now — we can use *others to assign everything else to the variable others.

person = ['bob', 'M', 20, 1.75, 70, 'black']

name, gender, *others = person

print(name, gender)

print(others)

We can switch the position of the variable with * too — in this example, we only need the first and last value, so we put *others in the middle.

person = ['bob', 'M', 20, 1.75, 70, 'black']

name, *others, hair = person

print(name, hair)

print(others)

In this example, we only need the last 2 values, so we can put *others at the front.

*others, weight, hair = person

print(weight)

print(hair)

print(others)

=========================================================================

7) Using * when combining iterables

We can also use * to combine iterables. Here, we combine 2 lists a & b by unpacking them into a list c.

a = [1, 2]

b = [3, 4]

c = [*a, *b]

print(c)

d = [[*a], [*b]]

print(d)

We can combine this technique with normal values like this:

a = [1, 2]

b = [3, 4]

c = [-1, 0, *a, *b, 5, 6]

print(c)

8) ** in combining dictionaries

** works for key-value mappings the same way * works for individual values. We can use ** to unpack dictionaries into other dictionaries in order to combine them.

x = {'a':1, 'b':2}

y = {'c':3, 'd':4}

z = {**x, **y}

print(z)


z = {**x, **y, 'e':5}

print(z)

=========================================================================

9) Importing everything from a module

We can also use from modulename import * to tell Python that we want to import everything that can be imported from some module.

from random import *

No comments:

Post a Comment