ይህ ትምህርት ገና ወደ አማርኛ አልተተረጎመም፤ ስለዚህ በእንግሊዝኛ ቀርቧል። የእንግሊዝኛውን ገጽ ክፈቱ
*args and **kwargs
print takes one value, or two, or ten. The functions you've written so far take an
exact number of arguments. By the end of this lesson you'll write functions that
accept any number, collect keyword arguments into a dict, and spread a list or dict
back out into a call.
Any number of arguments
A star before a parameter collects the arguments. Predict what args is:
ውጤቱን ገምቱ
Decide before you look. Guessing wrong is how this sticks.
def total(*args):
print(args)
total(120, 80, 45)Python prints
(120, 80, 45)
*args collects every positional argument into one tuple, so printing it shows parentheses. It's one value holding three numbers, not three values.
gathers the positional arguments into a tuple (lesson 4.3), so you can loop over it,
sum it, or ask its len. With no arguments it's an empty tuple, (). The name args
is only a convention; the star does the work, and *prices would read better here.
def total(*prices):
print(type(prices))
return sum(prices)
print(total(120, 80, 45))
print(total())In the editor, press Escape then Tab to move on.
Now total works for three prices or none. The catch is that it wants separate
arguments. Hand it a list and the list becomes one item of the tuple:
ጥያቄ
In def total(*args), called as total(1, 2), what type is args?
Any number of keyword arguments
Two stars collect keyword arguments instead, into a dict: each argument's name becomes a key and its value the value. A receipt can then take whatever the customer ordered:
def receipt(**kwargs):
for item, price in kwargs.items():
print(f"{item}: {price} birr")
print(f"Total: {sum(kwargs.values())} birr")
receipt(coffee=40, bread=25, tea=15)In the editor, press Escape then Tab to move on.
("keyword arguments") keeps the order you passed them in, as dicts do.
Spreading values into a call
The stars work the other way in a call. * before a list spreads its items out as
separate positional arguments, and ** before a dict spreads it out as keyword
arguments. This is
.
Compare the two prints:
items = ["coffee", "bread", "tea"]
print(items)
print(*items)In the editor, press Escape then Tab to move on.
The first print gets one list. The second gets three strings, as if you'd written
print("coffee", "bread", "tea"). A dict's keys must match the parameter names:
def fare(km, base=20, per_km=5):
return base + km * per_km
options = {"km": 10, "per_km": 8}
print(fare(**options))In the editor, press Escape then Tab to move on.
That's fare(km=10, per_km=8), so base keeps its default.
When to use them
Stars are for helpers that really take "any number": a total, an average, a function
that passes its arguments on to another. Most functions shouldn't use them. With
def fare(km, base=20, per_km=5), the def line tells a reader exactly what to pass,
and a typo like per_kn=8 is an error instead of a key nobody reads. Reach for *args
when the count really varies, not to avoid naming parameters.
መልመጃ
An average of any number of scores
Write average(*scores) returning the average of the scores. With no scores it should
return 0 instead of crashing (dividing by len(scores), which is 0, would be a
ZeroDivisionError).
79.0
0Your code
def average(*scores):
# Return 0 when there are no scores
return sum(scores) / len(scores)
print(average(80, 90, 67))
print(average())In the editor, press Escape then Tab to move on.
መፍትሄውን አሳይHide the solution
This is one way to solve it, not the only one. If yours prints the same thing, it works.
def average(*scores):
if len(scores) == 0:
return 0
return sum(scores) / len(scores)
print(average(80, 90, 67))
print(average())ዋና ዋና ነጥቦች
*argscollects any number of positional arguments into a tuple.**kwargscollects any number of keyword arguments into a dict.- In a call,
*itemsspreads a list into separate arguments, and**optionsspreads a dict into keyword arguments. - Passing a list to
*argsgives a tuple holding one list; spread it with*instead. - Use stars when the count really varies; name your parameters everywhere else.