我有一个C ++背景,我正在学习Python。我正在编写需要从for
循环中提取特定值的代码:
seventh_value = None # ** my question is about this line
for index in range(1, 10):
value = f(index)
# we have a special interest in the seventh value
if index == 7:
seventh_value = value
# (do other things with value here)
# make use of seventh_value here
在C ++中,我需要在for循环之前声明seven_value,以确保其范围不限于for循环。在Python中我不需要这样做。我的问题是,省略初始赋值给seven_value是否是一种好的风格。
我理解如果循环没有迭代至少7次,那么我可以通过在循环之前分配到seventh_value来避免NameError。让我们假设很明显它会迭代至少7次(如上面的例子,我已经硬编码了10次迭代)。
我也理解可能有其他方法从迭代中提取特定值。我真的只是想知道在循环之前引入变量是否是好的风格,如果它们将在循环之后使用。
我上面写的代码对我来说很清楚,但我认为我只是用C ++眼睛看到它。
答案 0 :(得分:2)
这是在for循环之前将值设置为None
的好方法。别担心。就个人而言,只要代码可以被完全不知道的人阅读 - 我就觉得很好。
话虽如此,有一种稍微好一点(pythonic)的方法可以完全避免这个问题。 注意以下不会对每次迭代的值执行任何操作 - 只是“特殊兴趣”部分。此外,我假设f(..)
不会引起任何副作用(比如变量状态变异(如全局变量)。如果是这样,下面的行肯定不适合你。
seventh_value = next(f(i) for i in range(1,10) if i == 7)
上述构造一直运行到i == 7,并且仅在i = 7时才调用f(i)
。
答案 1 :(得分:1)
这只是风格问题的一部分。您需要执行某些以确保您的代码不会在循环后引发(未捕获)NameError
,因此您的两个选择是
通过对NameError
进行无条件分配,确保seventh_value
不会发生。
包含访问seventh_value
块中try
的代码以捕获并(可能)忽略可能的NameError
。
从这个角度来看,在不了解您的代码的情况下,我认为您会同意#1更为可取。
答案 2 :(得分:1)
如果您确定应该设置seventh_value
并且在程序逻辑中依赖它,那么您甚至可能希望代码在NameError
时崩溃并在不事先seventh_value
的情况下编写代码定义
如果您确定在所有代码都正常工作时可能未设置seventh_value
,则应该像在示例中那样定义seventh_value
,并在以后检查它是否设置完毕。< / p>
答案 3 :(得分:0)
你可以完全按照你的建议去做,如果你尝试的话,你会发现它的功能完全符合你的需要。
然而,有一种更好的(imho更pythonic)方式,完全避免了预先初始化变量的需要。
results = []
for index in range(1, 10):
value = f(index)
# (do other things with value here)
results.append(value)
seventh_value = results[6] #6 because index 1 is at location 0 in the list.
# make use of seventh_value here
既然你有一个简单的for
循环,它可以很容易地重构为列表理解:
results = [f(index) for index in range(1, 10)]
for value in results:
# (do other things with value here)
seventh_value = results[7]
# make use of seventh_value here
您是否决定走这么远将取决于(do other things with value here)
的复杂程度。