在Django中,是否有为QuerySet编写复杂的自定义过滤器的标准方法?
正如我可以写的那样
MyClass.objects.all().filter(field=val)
Run Code Online (Sandbox Code Playgroud)
我想做这样的事情:
MyClass.objects.all().filter(customFilter)
Run Code Online (Sandbox Code Playgroud)
我可以使用生成器表达式
(x for x in MyClass.objects.all() if customFilter(x))
Run Code Online (Sandbox Code Playgroud)
但这会失去可链接性以及QuerySets提供的任何其他功能.
考虑以下函数,其输出应该是一系列迭代的笛卡尔积:
def cart(*iterables):
out = ((e,) for e in iterables[0])
for iterable in iterables[1:]:
out = (e1 + (e2,) for e1 in out for e2 in iterable)
return out
Run Code Online (Sandbox Code Playgroud)
当生成器理解被列表推导替换时,工作正常.当只有2个迭代时也可以工作.但是,当我尝试
print(list(cart([1, 2, 3], 'ab', [4, 5])))
Run Code Online (Sandbox Code Playgroud)
我明白了
[(1, 4, 4), (1, 4, 5), (1, 5, 4), (1, 5, 5),
(2, 4, 4), (2, 4, 5), (2, 5, 4), (2, 5, 5),
(3, 4, 4), (3, 4, 5), (3, 5, 4), (3, 5, 5)]
Run Code Online (Sandbox Code Playgroud)
为什么这个而不是笛卡儿产品?
print max(3 for i in range(4))
#output is 3
Run Code Online (Sandbox Code Playgroud)
使用Python 2.6
3让我失望,继承人我试图解释最新情况.
for range in range(4)使循环循环4次,在每个循环开始时将i从0递增到3.[不知道3在这种情况下意味着什么......] max()返回传递给它的最大迭代次数,结果打印到屏幕上.
我有这个:
>>> sum( i*i for i in xrange(5))
Run Code Online (Sandbox Code Playgroud)
我的问题是,在这种情况下,我是否将列表理解或生成器对象传递给总和?我怎么说呢?围绕这个有一般规则吗?
另外,请记住sum本身需要一对括号来包围它的参数.我认为上面的括号是求和而不是创建生成器对象.你不同意吗?
在下面的:
name = 'TODD'
chars = set('AEIOU')
for ii in range(-1, int(math.copysign(len(name) + 1, -1)), -1):
if any((cc in chars) for cc in name[ii]):
print 'Found'
else:
print 'Not Found'
Run Code Online (Sandbox Code Playgroud)
我知道任何(...)里面的东西都是生成器对象.我不明白的是缺少括号 - 如果括号属于any()函数,那么生成器表达式周围是否应该有另一组括号?
谢谢.
我在Windows上使用Python 3.3.1 64位和此代码片段:
len ([None for n in range (1, 1000000) if n%3 == 1])
Run Code Online (Sandbox Code Playgroud)
与此相比,执行时间为136毫秒:
sum (1 for n in range (1, 1000000) if n%3 == 1)
Run Code Online (Sandbox Code Playgroud)
在146ms执行.在这种情况下,生成器表达式不应该比列表理解更快或更快吗?
我引用了Guido van Rossum 从列表理解到生成器表达式:
... Python 3中的列表推导和生成器表达式实际上比它们在Python 2中更快!(并且两者之间不再存在速度差异.)
编辑:
我测量了时间timeit
.我知道它不是很准确,但我只关心这里的相对速度,当我用不同的迭代次数测试时,我的列表理解版本的时间总是缩短.
我有一个生成器函数,我想从另一个函数调用并返回获得的生成器.我可以在这看到两种方法 -
注意,下面的函数是简单的虚函数来说明目的.请不要提出更好的方法来实现这些功能.
方法1def fun_a(n):
for i in range(n):
yield i+10
def fun_b(n):
if n < 0:
yield None
return
yield fun_a(n)
Run Code Online (Sandbox Code Playgroud)
并用它list(list(fun_b(10))[0])
来获取[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
def fun_b(n):
if n < 0:
yield None
return
for i in fun_a(n):
yield i
Run Code Online (Sandbox Code Playgroud)
然后list(fun_b(10))
可以给我[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
.
虽然方法1似乎很好,但我不想返回列表列表,因为在其他情况下我返回一个列表而我不想搞砸我的代码.方法2效率低下.
处理这种情况的最佳方法是什么?
我刚刚阅读了为什么 Python 中没有元组理解的问题?
在接受的答案的评论中,指出没有真正的“元组理解”。相反,我们当前的选择是使用生成器表达式并将生成的生成器对象传递给元组构造函数:
tuple(thing for thing in things)
Run Code Online (Sandbox Code Playgroud)
或者,我们可以使用列表推导式创建一个列表,然后将该列表传递给元组构造函数:
tuple([thing for thing in things])
Run Code Online (Sandbox Code Playgroud)
最后,与接受的答案相反,最近的一个答案指出元组推导确实是一件事(自 Python 3.5 起),使用以下语法:
*(thing for thing in things),
Run Code Online (Sandbox Code Playgroud)
在我看来,第二个示例似乎也是首先创建生成器对象的示例。这样对吗?
就幕后发生的事情而言,这些表达之间有什么区别吗?在性能方面?我假设第一个和第三个可能有延迟问题,而第二个可能有内存问题(如链接评论中所述)。
更新:
正如预期的那样,列表理解确实要快得多。我不明白为什么第一个比第三个快。有什么想法吗?
>>> from timeit import timeit
>>> a = 'tuple(i for i in range(10000))'
>>> b = 'tuple([i for i in range(10000)])'
>>> c = '*(i for i in range(10000)),'
>>> print('A:', timeit(a, number=1000000))
>>> print('B:', timeit(b, number=1000000))
>>> print('C:', timeit(c, number=1000000))
A: …
Run Code Online (Sandbox Code Playgroud) python tuples list-comprehension generator-expression python-3.x
我编写了算法,直到2周前它都可以正常工作。我收到此警告,但我不明白为什么得到它。警告是:
“ C:/Users/Administrator/Documents/Python/sezg_1_diffne.py:147:弃用警告:不建议调用np.sum(generator),将来会给出不同的结果。请使用np.sum(np.from_iter(generator) ))或内置的python sum。obje_1 = detmas.objVal + sum(hopen [i] * fixedCost for i in Fset)“
我的代码的一部分是:
obje_1=detmas.objVal+sum(hopen[i]*fixedCost for i in Fset)
Run Code Online (Sandbox Code Playgroud)
我尝试了一些在互联网上找到的东西,例如删除numpy并重新安装它。但是这些解决方案不适用于我的代码。我该如何解决?提前致谢...
I was just messing around in the Python interpreter and I came across some unexpected behavior.
>>> bools = (True, True, True, False)
>>> all(bools)
False
>>> any(bools)
True
Run Code Online (Sandbox Code Playgroud)
Ok, so far nothing out of the ordinary...
>>> bools = (b for b in (True, True, True, False))
>>> all(bools)
False
>>> any(bools)
False
Run Code Online (Sandbox Code Playgroud)
Here's where things start getting spooky. I figure this happens because the all
function iterates over the generator expression, calling its __next__
method and using up …