【问题标题】:Python global and local variable: How does the code work?Python 全局和局部变量:代码是如何工作的?
【发布时间】:2021-05-18 15:37:09
【问题描述】:

我遇到了一个允许用户输入水果名称的代码。根据输入,从篮子列表中搜索,如果水果在列表中,则显示其数量。

如果没有找到水果,用户可以输入该水果的数量并将其添加到列表中。

basket = [
    {'fruit': 'apple', 'qty': 20},
    {'fruit': 'banana', 'qty': 30},
    {'fruit': 'orange', 'qty': 10}
]

fruit = input('Enter a fruit:')

index = 0
found_it = False

while index < len(basket):
    item = basket[index]
    # check the fruit name
    if item['fruit'] == fruit:
        found_it = True
        print(f"Basket has {item['qty']} {item['fruit']}(s)")
        break

    index += 1

if not found_it:
    qty = int(input(f'Enter the qty for {fruit}:'))
    basket.append({'fruit': fruit, 'qty': qty})
    print(basket)

但我不明白外部 if 条件的逻辑。它指的是哪个found_it?在(全局)while 语句之前定义的一个还是在其中定义的一个(本地)?外部if 是如何工作的?

【问题讨论】:

  • 这里的全局/本地范围没有变化。本地found_it 变量最初设置为False,然后如果在while 循环中找到匹配项,则设置为True。这样,当循环结束时,如果在列表中没有找到水果,它只会运行最后的代码。
  • 你的代码只有一个变量'found_it',你的循环有条件地修改它。 if语句用于检查是否在循环的迭代过程中被修改。
  • 哦,这背后的逻辑是,如果我键入“python”,while 语句会遍历列表直到index >=len(basket) 并呈现while 条件False。然后它退出 while 循环而不中断。此时,found_it 仍然是第一次分配的False,因为在水果篮中找不到“python”,因此在 while 循环中没有修改 found_it。因此,执行外部 if 语句,因为 False 不是 True。这是正确的吗?

标签: python for-loop while-loop global-variables local-variables


【解决方案1】:

这并不是真正的答案,而是向您展示了如何回避使用可变值来决定下一步该做什么的问题。


请注意,Python 有一个 while-else 构造,这使得 found_it 变量变得不必要。

basket = [
    {'fruit': 'apple', 'qty': 20},
    {'fruit': 'banana', 'qty': 30},
    {'fruit': 'orange', 'qty': 10}
]

fruit = input('Enter a fruit:')

index = 0

while index < len(basket):
    item = basket[index]
    # check the fruit name
    if item['fruit'] == fruit:
        print(f"Basket has {item['qty']} {item['fruit']}(s)")
        break

    index += 1
else:
    qty = int(input(f'Enter the qty for {fruit}:'))
    basket.append({'fruit': fruit, 'qty': qty})
    print(basket)

循环的else 子句仅在break 未用于退出循环时执行,即当您更改found_it 的值时。


有点不相关,你可以直接遍历basket的元素,不用担心索引。

basket = [
    {'fruit': 'apple', 'qty': 20},
    {'fruit': 'banana', 'qty': 30},
    {'fruit': 'orange', 'qty': 10}
]

fruit = input('Enter a fruit:')

for item in basket:
    # check the fruit name
    if item['fruit'] == fruit:
        print(f"Basket has {item['qty']} {item['fruit']}(s)")
        break
else:
    qty = int(input(f'Enter the qty for {fruit}:'))
    basket.append({'fruit': fruit, 'qty': qty})
    print(basket)

elsefor 的行为方式与 while 相同:它仅在循环“自然”退出时执行,在这种情况下,通过耗尽迭代器而不是当循环条件变为 false 时执行。

【讨论】:

    【解决方案2】:

    在 python 中,您不需要显式声明变量。这可能会令人困惑,但是一旦变量存在于范围内,在这种情况下是全局变量,那么分配给它会改变它的值,而不是创建一个新变量。最好的时刻是当你拼错某些东西时,python 会认为你用那个值声明了新变量,而原来的变量不会改变。我真的不明白为什么 python 的创建者会引入这种歧义,幸运的是新语言避免了这个错误。

    【讨论】:

    • 哦,但是局部变量和全局变量可以同名吗?如果是这样,python如何区分它们?例如,如果我想将counter 变量放入函数或循环中,我必须首先在函数/循环之外定义它,否则会出现错误并且无法识别counter。在这种情况下,函数/循环外部和内部的counter 是具有相同名称的全局变量和局部变量(分别)对吧?
    • 范围是嵌套的;名称指的是最近包含范围内的变量。 nonlocalglobal 关键字用于在更高范围内分配变量,而不在当前范围内创建新变量。
    • 如果当前作用域中存在同名变量之一,则无法引用更高作用域中的变量。
    【解决方案3】:

    使用调试器运行代码表明,一旦遇到第一个found_it,它就会在全局和本地创建,因此内部循环中的found_it 会更改您最初声明的值。

    关于外循环的工作,if not 是一个检查真假的条件,即只有当值为假时才会执行。

    使用普通的if-else 会更容易。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-24
      • 2018-10-26
      • 2022-11-16
      • 2022-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多