yieldPython中关键字的用途是什么?它有什么作用?
例如,我试图理解这段代码1:
def _get_child_candidates(self, distance, min_dist, max_dist):
if self._leftchild and distance - max_dist < self._median:
yield self._leftchild
if self._rightchild and distance + max_dist >= self._median:
yield self._rightchild
Run Code Online (Sandbox Code Playgroud)
这是来电者:
result, candidates = [], [self]
while candidates:
node = candidates.pop()
distance = node._get_dist(obj)
if distance <= max_dist and distance >= min_dist:
result.extend(node._values)
candidates.extend(node._get_child_candidates(distance, min_dist, max_dist))
return result
Run Code Online (Sandbox Code Playgroud)
_get_child_candidates调用该方法时会发生什么?列表是否返回?单个元素?它又被召唤了吗?后续通话何时停止?
1.代码来自Jochen Schulz(jrschulz),他为度量空间创建了一个很棒的Python库.这是完整源代码的链接:模块mspace.
什么时候应该使用生成器表达式?什么时候应该在Python中使用列表推导?
# Generator expression
(x*2 for x in range(256))
# List comprehension
[x*2 for x in range(256)]
Run Code Online (Sandbox Code Playgroud) 这里的讨论提示
是否应将等效代码的行为视为定义的一部分,或者实现是否可以以非短路方式实现它们?
以下是cpython/Lib/test/test_builtin.py的相关摘录
def test_all(self):
self.assertEqual(all([2, 4, 6]), True)
self.assertEqual(all([2, None, 6]), False)
self.assertRaises(RuntimeError, all, [2, TestFailingBool(), 6])
self.assertRaises(RuntimeError, all, TestFailingIter())
self.assertRaises(TypeError, all, 10) # Non-iterable
self.assertRaises(TypeError, all) # No args
self.assertRaises(TypeError, all, [2, 4, 6], []) # Too many args
self.assertEqual(all([]), True) # Empty iterator
S = [50, 60]
self.assertEqual(all(x > 42 for x in S), True)
S = [50, 40, 60]
self.assertEqual(all(x > 42 for x in S), False)
def test_any(self): …Run Code Online (Sandbox Code Playgroud) 我目前正在这样做:
if x in a and y in a and z in a and q in a and r in a and s in a:
print b
Run Code Online (Sandbox Code Playgroud)
是否有更多的pythonic方式来表达这种if说法?
这是在处理Django项目时遇到的问题.这是关于表单验证.
在Django中,当您有一个提交的表单时,您可以调用is_valid()相应的表单对象来触发验证并返回一个布尔值.所以,通常你在视图函数中有这样的代码:
if form.is_valid():
# code to save the form data
Run Code Online (Sandbox Code Playgroud)
is_valid() 不仅验证表单数据,还将错误消息添加到表单对象,然后可以向用户显示.
在一个页面上,我一起使用两个表单,并且只有在两个表单都包含有效数据时才希望保存数据.这意味着我必须在执行代码保存数据之前在两个表单上调用is_valid().最明显的方式:
if form1.is_valid() and form2.is_valid():
# ...
Run Code Online (Sandbox Code Playgroud)
由于逻辑运算符的短路评估,将无法工作.如果form1无效,则不会评估form2,并且将丢失其错误消息.
这只是一个例子.据我所知,没有贪婪替代and/ or在其他语言(如Smalltalk的).我可以想象在不同情况下(而不仅仅是在Python中)发生的问题.我能想到的解决方案都是笨拙的(嵌套ifs,将返回值赋给局部变量并在if语句中使用它们).我想知道解决这类问题的pythonic方法.
提前致谢!
我想确定列表是否包含某个字符串,所以我使用生成器表达式,如下所示:
g = (s for s in myList if s == myString)
any(g)
Run Code Online (Sandbox Code Playgroud)
当然我想内联这个,所以我这样做:
any((s for s in myList if s == myString))
Run Code Online (Sandbox Code Playgroud)
然后我认为单个parens会更好看,所以我尝试:
any(s for s in myList if s == myString)
Run Code Online (Sandbox Code Playgroud)
并不是真的期待它的运作.惊喜!它呢!
那么这个合法的Python还是我的实现允许的东西?如果它是合法的,这里的一般规则是什么?
例如:
def foo():
print 'foo'
return 1
if any([f() for f in [foo]*3]):
print 'bar'
Run Code Online (Sandbox Code Playgroud)
我认为上面的代码应该输出:
foo
bar
Run Code Online (Sandbox Code Playgroud)
代替 :
foo
foo
foo
bar
Run Code Online (Sandbox Code Playgroud)
为什么?我怎样才能产生"短路"效应?
Python 中的逻辑运算符是惰性的。具有以下定义:
def func(s):
print(s)
return True
Run Code Online (Sandbox Code Playgroud)
呼叫or接线员
>>> func('s') or func('t')
's'
Run Code Online (Sandbox Code Playgroud)
只计算第一个函数调用,因为or识别表达式计算为
True,而不管第二个函数调用的返回值。and行为类似。
但是,当以下列方式使用any()(类比:)时all():
>>> any([func('s'), func('t')])
's'
't'
Run Code Online (Sandbox Code Playgroud)
所有函数调用都会被评估,因为在any开始迭代其项目的布尔值之前,首先构造内部列表。当我们省略列表构造而只写时,也会发生同样的情况
>>> func('s') or func('t')
's'
Run Code Online (Sandbox Code Playgroud)
这样,我们失去的力量any是短路,它只要迭代的第一个元素是truish打破该装置。如果函数调用代价高昂,那么预先评估所有函数是一个很大的损失,并且浪费了any. 从某种意义上说,人们可以将其称为 Python 陷阱,因为对于尝试利用 的此功能的用户来说可能出乎意料any,并且any通常被认为只是链接一系列or语句的另一种语法方式。但any只是短路,而不是懒惰,这就是这里的区别。
any正在接受一个 iterable。因此,应该有一种创建迭代器的方法,该迭代器不会预先评估其元素,而是将未评估的元素传递给any并让它们any仅在内部评估,以实现完全懒惰的评估。
所以,问题是:我们如何使用any真正的惰性函数评估?这意味着:我们如何制作一个any可以消费的函数调用迭代器,而无需预先评估所有函数调用?
all()在序列中找到 False 后是否立即返回 False?
尝试运行这段代码:
def return_true():
print('I have just been printed')
return True
print(all((False, return_true())))
Run Code Online (Sandbox Code Playgroud)
如您所见,I have just been printed即使前面有 False,也会打印出来。
另一个例子:
def return_false():
print('I have just been printed')
return False
print(any((True, return_false())))
Run Code Online (Sandbox Code Playgroud)
在这种情况下,I have just been printed即使之前有 True,也会在此代码中打印。
例如:我有一个名为 的列表container。其中有一些元素,我想检查是否例如。其中任何一个都很复杂。
container = [1, 0.5, "text", 1j]
if isinstance(container[?], complex):
print("This list has complex elements")
Run Code Online (Sandbox Code Playgroud)
在这个例子中,我可以写container[-1],但是有通用的方法吗?我可以使用 for 循环,但我想知道是否有更好的方法来做到这一点。
python ×10
generator ×2
any ×1
coroutine ×1
if-statement ×1
iterator ×1
parentheses ×1
yield ×1