Python 基础四

今天学习Python 的基础语法控制流。

while循环

For 循环是一种“有限迭代”,意味着循环主体将运行预定义的次数。这与“无限迭代”循环不同,无限迭代循环是指循环重复未知次数,并在满足某个条件时结束,while 循环正是这种情况。下面是一个 while 循环的示例。

card_deck = [4, 11, 8, 5, 13, 2, 8, 10]
hand = []

# adds the last element of the card_deck list to the hand list
# until the values in hand add up to 17 or more
while sum(hand)  <= 17:
    hand.append(card_deck.pop())

这个示例包含两个函数。sum 返回列表中的元素之和,pop 是一个列表方法,它会从列表中删除最后一个元素并返回该元素。

While 循环的组成部分

  • 1、第一行以关键字 while 开始,表示这是一个 while 循环。
  • 2、然后是要检查的条件。在此示例中是 sum(hand) <= 17。
  • 3、while 循环头部始终以冒号 : 结束。
  • 4、该头部之后的缩进部分是 while 循环的主体。如果 while 循环的条件为 true,该循环的主体将被执行。每次运行循环主体时,条件将被重新评估。这个检查条件然后运行循环的流程将重复,直到该表达式变成 false。

循环的缩进主体应该至少修改测试表达式中的一个变量。如果测试表达式的值始终不变,就会变成无限循环!

Break、Continue

有时候我们需要更精准地控制何时循环应该结束,或者跳过某个迭代。在这些情况下,我们使用关键字 breakcontinue,这两个关键字可以用于 forwhile 循环。

  • break 使循环终止
  • continue 跳过循环的一次迭代

示例

manifest = [("bananas", 15), ("mattresses", 24), ("dog kennels", 42), ("machine", 120), ("cheeses", 5)]

# the code breaks the loop when weight exceeds or reaches the limit
print("METHOD 1")
weight = 0
items = []
for cargo_name, cargo_weight in manifest:
    print("current weight: {}".format(weight))
    if weight >= 100:
        print("  breaking loop now!")
        break
    else:
        print("  adding {} ({})".format(cargo_name, cargo_weight))
        items.append(cargo_name)
        weight += cargo_weight

print("\nFinal Weight: {}".format(weight))
print("Final Items: {}".format(items))

截取字符串:
用 break 语句写一个循环,用于创建刚好长 140 个字符的字符串 news_ticker。你应该通过添加 headlines 列表中的新闻标题创建新闻提醒,在每个新闻标题之间插入空格。如果有必要的话,将最后一个新闻标题从中间截断,使 news_ticker 刚好长 140 个字符。

注意,break 同时适用于 for 和 while 循环。使用你认为最合适的循环。考虑向代码中添加 print 语句以帮助你解决 bug。

# HINT: modify the headlines list to verify your loop works with different inputs
headlines = ["Local Bear Eaten by Man",
             "Legislature Announces New Laws",
             "Peasant Discovers Violence Inherent in System",
             "Cat Rescues Fireman Stuck in Tree",
             "Brave Knight Runs Away",
             "Papperbok Review: Totally Triffic"]

news_ticker = ""
# write your loop here

for title in headlines:
    news_ticker += title + " "
    if len(news_ticker) >= 140:
        news_ticker = news_ticker[0:140]
                break

print(news_ticker)

Zip 和 Enumerate

zip 和 enumerate 是实用的内置函数,可以在处理循环时用到。

Zip

zip 返回一个将多个可迭代对象组合成一个元组序列的迭代器。每个元组都包含所有可迭代对象中该位置的元素。例如,

list(zip(['a', 'b', 'c'], [1, 2, 3]))将输出[('a', 1), ('b', 2), ('c', 3)].

正如 range()一样,我们需要将其转换为列表或使用循环进行遍历以查看其中的元素。
你可以如下所示地用 for 循环拆封每个元组。

letters = ['a', 'b', 'c']
nums = [1, 2, 3]

for letter, num in zip(letters, nums):
    print("{}: {}".format(letter, num))

输出:

a: 1
b: 2
c: 3

除了可以将两个列表组合到一起之外,还可以使用星号拆封列表。

some_list = [('a', 1), ('b', 2), ('c', 3)]
letters, nums = zip(*some_list)

这样可以创建正如之前看到的相同 letters 和 nums 列表。

Enumerate

enumerate 是一个会返回元组迭代器的内置函数,这些元组包含列表的索引和值。当你需要在循环中获取可迭代对象的每个元素及其索引时,将经常用到该函数。

letters = ['a', 'b', 'c', 'd', 'e']
for i, letter in enumerate(letters):
    print(i, letter)

这段代码将输出:

0 a
1 b
2 c
3 d
4 e

练习:组合坐标

使用 zip 写一个 for 循环,该循环会创建一个字符串,指定每个点的标签和坐标,并将其附加到列表 points。每个字符串的格式应该为 label: x, y, z。例如,第一个坐标的字符串应该为 F: 23, 677, 4。

x_coord = [23, 53, 2, -12, 95, 103, 14, -5]
y_coord = [677, 233, 405, 433, 905, 376, 432, 445]
z_coord = [4, 16, -6, -42, 3, -6, 23, -1]
labels = ["F", "J", "A", "Q", "Y", "B", "W", "X"]

points = []
# write your for loop here

for label,x,y,z in zip(labels,x_coord,y_coord,z_coord):
    # print("{}: {},{},{}".format(label,x,y,z))
    tmp = "{}: {}, {}, {}".format(label,x,y,z)
    points.append(tmp)

for point in points:
    print(point)

练习:将列表组合成字典

使用 zip 创建一个字典 cast,该字典使用 names 作为键,并使用 heights 作为值。

cast_names = ["Barney", "Robin", "Ted", "Lily", "Marshall"]
cast_heights = [72, 68, 72, 66, 76]

# cast = # replace with your code
cast = {} # 创建一个空字典
for name,height in zip(cast_names,cast_heights):
    cast[name] = height

print(cast)

打印:

{'Marshall': 76, 'Barney': 72, 'Lily': 66, 'Robin': 68, 'Ted': 72}

拆封元组

将 cast 元组拆封成两个 names 和 heights 元组。

cast = (("Barney", 72), ("Robin", 68), ("Ted", 72), ("Lily", 66), ("Marshall", 76))

# define names and heights here
names,heights = zip(*cast)

print(names)
print(heights)

用 Zip 进行转置

data = ((0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11))

data_transpose = tuple(zip(*data))
print(data_transpose)

输出:

((0, 3, 6, 9), (1, 4, 7, 10), (2, 5, 8, 11))

列表推导式

在 Python 中,你可以使用列表推导式快速简练地创建列表。下面是之前的一个示例:

capitalized_cities = []
for city in cities:
    capitalized_cities.append(city.title())

可以简写为:

capitalized_cities = [city.title() for city in cities]

借助列表推导式,我们可以使用 for 循环用一步创建一个列表。

我们使用方括号 [] 创建列表推导式,括号里包含要对可迭代对象中的每个元素进行评估的条件。上述列表推导式对 cities 中的每个元素 city 调用 city.title(),以为新列表 capitalized_cities 创建每个元素。

列表推导式中的条件语句

你还可以向列表推导式添加条件语句。在可迭代对象之后,你可以使用关键字 if 检查每次迭代中的条件。

squares = [x**2 for x in range(9) if x % 2 == 0]

上述代码将 squares 设为等于列表 [0, 4, 16, 36, 64],因为仅在 x 为偶数时才评估 x 的 2 次幂。如果你想添加 else,将遇到语法错误。

squares = [x**2 for x in range(9) if x % 2 == 0 else x + 3]

如果你要添加 else,则需要将条件语句移到列表推导式的开头,直接放在表达式后面,如下所示。

squares = [x**2 if x % 2 == 0 else x + 3 for x in range(9)]

列表推导式并没有在其他语言中出现,但是在 python 中很常见。

为者常成,行者常至