Python 的星号表达式可以用来解决这个问题。比如,你在学习一门课程,在学期末的时候,你想统计下家庭作业的平均成绩,但是排除掉第一个和最后一个分数。如果只有四个分数,你可能就直接去简单的手动赋值,但如果有 24 个呢?这时候星号表达式就派上用场了:
record = ('Dave', 'dave@example.com', '773-555-1212', '847-555-1212')
name, email, *phone_numbers = record
print(name)
print(phone_numbers)
另外一种情况,假设你现在有一些用户的记录列表,每条记录包含一个名字、邮件,接着就是不确定数量的电话号码。你可以像下面这样分解这些记录:
note:列表是可变的,这意味着它们的元素可以被修改,而元组是不可变的,这意味着它们的元素不能被修改,使用元组而不是列表 grades,元组解包仍将有效,但avg(middle)函数调用将无法修改middle元组,因为元组是不可变的
列表版本
def avg(numbers):
"""Calculate the average of a list of numbers."""
if not numbers:
return 0
return sum(numbers) / len(numbers)
def drop_first_last(grades):
first, *middle, last = grades
average_middle_grades = avg(middle)
print(f"First grade: {first}")
for grade in middle:
print(f"Middle grade: {grade}")
print(f"Last grade: {last}")
print(f"Average of middle grades: {average_middle_grades}")
return average_middle_grades
grades = [90, 85, 92, 88, 82, 87]
average_middle_grades = drop_first_last(grades)
print(average_middle_grades) # Output: 86.75
tuple版本
def avg(numbers):
"""Calculate the average of a list of numbers."""
if not numbers:
return 0
return sum(numbers) / len(numbers)
def drop_first_last(grades):
first, *middle, last = grades
average_middle_grades = avg(middle)
print(f"First grade: {first}")
for grade in middle:
print(f"Middle grade: {grade}")
print(f"Last grade: {last}")
print(f"Average of middle grades: {average_middle_grades}")
return average_middle_grades
grades = (90, 85, 92, 88, 82, 87)
average_middle_grades = drop_first_last(grades)
print(average_middle_grades) # Output: 86.75
生成器
def frange(start, stop, increment):
x = start
while x < stop:
yield x
x += increment
for n in frange(0, 4, 0.5):
print(n)
def countdown(n):
print('Starting to count from', n)
while n > 0:
yield n
n -= 1
print('Done!')
c = countdown(3)
print(c) # Output: <generator object countdown at 0x10fea8110>
print(next(c))
# Run to the next yield
print(next(c))
# Run to the next yield
print(next(c))
# Run to the next yield
print(next(c))
一个生成器函数主要特征是它只会回应在迭代中使用到的 next 操作。一旦生成器=函数返回退出,迭代终止。我们在迭代中通常使用的 for 语句会自动处理这些细节,所以你无需担心。