Flashield's Blog

Just For My Daily Diary

Flashield's Blog

Just For My Daily Diary

05.exercise-loops-and-list-comprehensions【练习:循环及列表推导式】

This notebook is an exercise in the Python course. You can reference the tutorial at this link.


Try It Yourself

With all you've learned, you can start writing much more interesting programs. See if you can solve the problems below.

As always, run the setup code below before working on the questions.

自己尝试一下

有了所学的知识,您就可以开始编写更有趣的程序了。 看看你能否解决下面的问题。

与往常一样,在解决问题之前运行下面的设置代码。

from learntools.core import binder; binder.bind(globals())
from learntools.python.ex5 import *
print('Setup complete.')
Setup complete.

Exercises

练习

1.

Have you ever felt debugging involved a bit of luck? The following program has a bug. Try to identify the bug and fix it.

1.

您是否曾经觉得调试需要一点运气? 下面的程序有一个错误。 尝试找出错误并修复它。

def has_lucky_number(nums):
    """Return whether the given list of numbers is lucky. A lucky list contains
    at least one number divisible by 7.
    """
    for num in nums:
        if num % 7 == 0:
            return True
    return False

Try to identify the bug and fix it in the cell below:

尝试找出错误并在下面的单元格中修复它:

def has_lucky_number(nums):
    """Return whether the given list of numbers is lucky. A lucky list contains
    at least one number divisible by 7.

    返回给定的数字列表是否是幸运的。 幸运名单包含至少一个能被 7 整除的数字。
    """
    for num in nums:
        if int(num % 7) == 0:
            return True
    return False

# Check your answer
q1.check()

Correct:

Remember that return causes a function to exit immediately. So our original implementation always ran for just one iteration. We can only return False if we've looked at every element of the list (and confirmed that none of them are lucky). Though we can return early if the answer is True:

def has_lucky_number(nums):
    for num in nums:
        if num % 7 == 0:
            return True
    # We've exhausted the list without finding a lucky number
    return False

Here's a one-line version using a list comprehension with Python's any function (you can read about what it does by calling help(any)):

def has_lucky_number(nums):
    return any([num % 7 == 0 for num in nums])
#q1.hint()
q1.solution()

Solution: Remember that return causes a function to exit immediately. So our original implementation always ran for just one iteration. We can only return False if we've looked at every element of the list (and confirmed that none of them are lucky). Though we can return early if the answer is True:

def has_lucky_number(nums):
    for num in nums:
        if num % 7 == 0:
            return True
    # We've exhausted the list without finding a lucky number
    return False

Here's a one-line version using a list comprehension with Python's any function (you can read about what it does by calling help(any)):

def has_lucky_number(nums):
    return any([num % 7 == 0 for num in nums])

2.

a.

Look at the Python expression below. What do you think we'll get when we run it? When you've made your prediction, uncomment the code and run the cell to see if you were right.

2.

a.

看看下面的Python 表达式。 你认为运行它后我们会得到什么? 当您做出预测后,取消注释代码并运行单元格以查看您是否正确。

[1, 2, 3, 4] > 2
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

Cell In[5], line 1
----> 1 [1, 2, 3, 4] > 2

TypeError: '>' not supported between instances of 'list' and 'int'

b

R and Python have some libraries (like numpy and pandas) compare each element of the list to 2 (i.e. do an 'element-wise' comparison) and give us a list of booleans like [False, False, True, True].

Implement a function that reproduces this behaviour, returning a list of booleans corresponding to whether the corresponding element is greater than n.

b

R 和 Python 有一些库(如 numpy 和 pandas)将列表中的每个元素与 2 进行比较(即进行逐元素比较),并为我们提供一个布尔值列表,如[False, False, True, True]

实现一个重现此行为的函数,返回与相应元素是否大于 n 相对应的布尔值列表。

def elementwise_greater_than(L, thresh):
    """Return a list with the same length as L, where the value at index i is 
    True if L[i] is greater than thresh, and False otherwise.
    返回与 L 长度相同的列表,其中索引 i 处的值为如果 L[i] 大于 thresh,则为 True,否则为 False。

    >>> elementwise_greater_than([1, 2, 3, 4], 2)
    [False, False, True, True]
    """
    # pass
    return [i > thresh for i in L]

# Check your answer
q2.check()

Correct:

Here's one solution:

def elementwise_greater_than(L, thresh):
    res = []
    for ele in L:
        res.append(ele > thresh)
    return res

And here's the list comprehension version:

def elementwise_greater_than(L, thresh):
    return [ele > thresh for ele in L]
q2.solution()

Solution: Here's one solution:

def elementwise_greater_than(L, thresh):
    res = []
    for ele in L:
        res.append(ele > thresh)
    return res

And here's the list comprehension version:

def elementwise_greater_than(L, thresh):
    return [ele > thresh for ele in L]

3.

Complete the body of the function below according to its docstring.

3.

根据文档字符串完成下面函数的主体。

def menu_is_boring(meals):
    """Given a list of meals served over some period of time, return True if the
    same meal has ever been served two days `in a row`, and False otherwise.

    给定一段时间内提供的餐食列表,如果连续两天供应过同一餐则返回True,否则为 False。
    """
    #pass
    for i in range(len(meals)-1):
        if meals[i] == meals[i+1]:
            return True
    return False

# Check your answer
q3.check()

Correct:

def menu_is_boring(meals):
    # Iterate over all indices of the list, except the last one
    for i in range(len(meals)-1):
        if meals[i] == meals[i+1]:
            return True
    return False

The key to our solution is the call to range. range(len(meals)) would give us all the indices of meals. If we had used that range, the last iteration of the loop would be comparing the last element to the element after it, which is... IndexError! range(len(meals)-1) gives us all the indices except the index of the last element.

But don't we need to check if meals is empty? Turns out that range(0) == range(-1) - they're both empty. So if meals has length 0 or 1, we just won't do any iterations of our for loop.

#q3.hint()
q3.solution()

Solution:

def menu_is_boring(meals):
    # Iterate over all indices of the list, except the last one
    for i in range(len(meals)-1):
        if meals[i] == meals[i+1]:
            return True
    return False

The key to our solution is the call to range. range(len(meals)) would give us all the indices of meals. If we had used that range, the last iteration of the loop would be comparing the last element to the element after it, which is... IndexError! range(len(meals)-1) gives us all the indices except the index of the last element.

But don't we need to check if meals is empty? Turns out that range(0) == range(-1) - they're both empty. So if meals has length 0 or 1, we just won't do any iterations of our for loop.

4. 🌶️

Next to the Blackjack table, the Python Challenge Casino has a slot machine. You can get a result from the slot machine by calling play_slot_machine(). The number it returns is your winnings in dollars. Usually it returns 0. But sometimes you'll get lucky and get a big payday. Try running it below:

在二十一点赌桌旁边,Python Challenge 赌场设有一台老虎机。 您可以通过调用play_slot_machine()从老虎机获取结果。 它返回的数字就是您赢得的美元奖金。 通常它返回 0。但有时你会很幸运并获得丰厚的回报。 尝试在下面运行它:

play_slot_machine()
0

By the way, did we mention that each play costs $1? Don't worry, we'll send you the bill later.

On average, how much money can you expect to gain (or lose) every time you play the machine? The casino keeps it a secret, but you can estimate the average value of each pull using a technique called the Monte Carlo method. To estimate the average outcome, we simulate the scenario many times, and return the average result.

Complete the following function to calculate the average value per play of the slot machine.

顺便问一下,我们有没有提到每场比赛花费 1 美元? 别担心,我们稍后会将账单寄给您。

平均而言,您每次玩这台机器时预计会获得(或损失)多少钱? 赌场对此保密,但您可以使用一种称为 蒙特卡罗方法 的技术来估计每次拉彩的平均值。 为了估计平均结果,我们多次模拟该场景,并返回平均结果。

完成以下函数来计算老虎机每次运行的平均值。

def estimate_average_slot_payout(n_runs):
    """Run the slot machine n_runs times and return the average net profit per run.
    Example calls (note that return value is nondeterministic!):

    运行老虎机 n_runs 次并返回每次运行的平均净利润。
    调用示例(请注意,返回值是不确定的!):
    >>> estimate_average_slot_payout(1)
    -1
    >>> estimate_average_slot_payout(1)
    0.5
    """
    sum_num = 0
    for i in range(n_runs):
        sum_num += play_slot_machine()
    return sum_num/n_runs
    #pass

When you think you know the expected value per spin, run the code cell below to view the solution and get credit for answering the question.

当您认为您知道每次旋转的预期值时,请运行下面的代码单元格来查看解决方案并因回答问题而获得奖励。

# Check your answer (Run this code cell to receive credit!)
q4.solution()

Solution:

The exact expected value of one pull of the slot machine is 0.025 - i.e. a little more than 2 cents. See? Not every game in the Python Challenge Casino is rigged against the player!

In order to get this answer, you'll need to implement the estimate_average_slot_payout(n_runs) function to simulate pulling the slot machine n_runs times. It should return the payout averaged over those n_runs.

Then, once the function is defined, in order to estimate the average slot payout, we need only call the function.

Because of the high variance of the outcome (there are some very rare high payout results that significantly affect the average) you might need to run your function with a very high value of n_runs to get a stable answer close to the true expectation. For instance, you might use a value for n_runs of 1000000.

Here's an example for how the function could look:

def estimate_average_slot_payout(n_runs):
    # Play slot machine n_runs times, calculate payout of each
    payouts = [play_slot_machine()-1 for i in range(n_runs)]
    # Calculate the average value
    avg_payout = sum(payouts) / n_runs
    return avg_payout

estimate_average_slot_payout(10000000)

This should return an answer close to 0.025!

Keep Going

Many programmers report that dictionaries are their favorite data structure. You'll get to learn about them (as well as strings) in the next lesson.

继续前进

许多程序员表示字典是他们最喜欢的数据结构。 您将在下一课中了解了解它们(以及字符串)。

05.exercise-loops-and-list-comprehensions【练习:循环及列表推导式】

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top