以下行为对我来说似乎有点违反直觉(Python 3.4):
>>> [(yield i) for i in range(3)]
<generator object <listcomp> at 0x0245C148>
>>> list([(yield i) for i in range(3)])
[0, 1, 2]
>>> list((yield i) for i in range(3))
[0, None, 1, None, 2, None]
Run Code Online (Sandbox Code Playgroud)
最后一行的中间值实际上并不总是None,它们是我们send进入生成器的任何东西,等价(我猜)到下面的生成器:
def f():
for i in range(3):
yield (yield i)
Run Code Online (Sandbox Code Playgroud)
令我感到有趣的是,这三条线路都很有用.该参考指出,yield仅在一个函数定义允许的(虽然我可能读错和/或它可能只是已经从旧版本复制).前两行在SyntaxErrorPython 2.7中生成,但第三行不生成.
而且,这似乎很奇怪
有人可以提供更多信息吗?
python yield list-comprehension generator generator-expression
根据http://hyperpolyglot.org/lisp,Clojure中唯一的谎言是false和nil.确实,令人惊讶的(Boolean. false)是,并非虚假:
user=> (if (Boolean. false) 1 2)
1
user=> (not (Boolean. false))
false
user=> (false? (Boolean. false))
false
Run Code Online (Sandbox Code Playgroud)
另一方面,它在某种程度上是错误的:
user=> (class false)
java.lang.Boolean
user=> (= false (Boolean. false))
true
Run Code Online (Sandbox Code Playgroud)
这是违反直觉的.这种行为有原因还是被忽视了?Clojure中的其他Java数据类型是否也会发生类似的事情?它在ClojureScript和ClojureCLR中是否相同,或者它是否特定于JVM版本?其他JVM Lisps,如Kawa或ABCL,是否表现出类似的行为(如果他们根本使用Java布尔值)?
我有一些使用numpy和R的C代码.在Windows上,它使用MSVC编译为.dll,可以从R动态加载并传递所有测试.但是,我没能让它在Debian上运行.
为了研究这个问题,我创建了以下minimal-ish示例:
#include <Python.h>
#include <Rinternals.h>
#include <numpy/arrayobject.h>
SEXP main() {
Py_Initialize();
import_array();
SEXP one = PROTECT(allocVector(INTSXP, 1));
INTEGER(one)[0] = 1;
npy_intp dims[1] = {1};
int data[1] = {1};
PyObject *another = PyArray_SimpleNewFromData(1, dims, NPY_INT, data);
Rprintf("Hello, %d ", INTEGER(one)[0] + *(int*)PyArray_DATA(another));
PyRun_SimpleString("print('worlds')");
UNPROTECT(1);
return one;
}
Run Code Online (Sandbox Code Playgroud)
我可以编译它
cl /I "C:\Program Files\R\R-3.2.0\include" /I "C:\Python34\include" /I "C:\Python34\Lib\site-packages\numpy\core\include" /c hello.c
link /dll /export:main hello.obj Rdll.lib C:/Python34/libs/python34.lib
Run Code Online (Sandbox Code Playgroud)
其中,Rdll.lib从创建%R_HOME%\bin\x64\R.dll用
pexports R.dll > R.exp
link /lib /def:R.exp /machine:x64 /out:Rdll.lib
Run Code Online (Sandbox Code Playgroud)
然后它可以从R使用:
> …Run Code Online (Sandbox Code Playgroud) 让我们假设我们需要一个接受任何类型的两个参数的函数,只要这两个参数具有相同的类型。您将如何使用 mypy 静态检查它?
如果我们只需要函数接受一些有限数量的已知类型,这很容易:
from typing import TypeVar, List, Callable
T = TypeVar('T', int, str, List[int], Callable[[], int])
def f(a: T, b: T) -> None:
pass
f(1, 2)
f("1", "2")
f([1], [2])
f(lambda: 1, lambda: 2)
f(1, "2") # mypy will print an error message
Run Code Online (Sandbox Code Playgroud)
对于此代码,mypy 可以确保 to 的参数f是两个ints 或两个strs 或两个ints列表或两个返回 的零参数函数int。
但是如果我们事先不知道类型怎么办?如果我们需要类似于let f (a:'t) (b:'t) = ()F# 和 OCaml 的东西怎么办?简单地写作T = TypeVar('T')会使事情变得f(1, "2")有效,这不是我们想要的。
让我们考虑打破一个非终止的折叠:
(call/cc (lambda (folded)
(stream-fold
(lambda (acc v)
(if (< v 5)
(cons v acc)
(folded acc)))
'()
(in-naturals 0))))
; returns '(4 3 2 1 0)
Run Code Online (Sandbox Code Playgroud)
Haskell相当于上面的代码
callCC $ \folded -> foldl (\acc v -> if v < 5 then v:acc else folded acc) [] [0..]
Run Code Online (Sandbox Code Playgroud)
此代码无法编译并抱怨无法在表达式折叠acc中构造无限类型.我已经知道如何在像Y组合器这样的情况下消除这种错误,但是同样的方法似乎在这里不起作用.这种情况的正确方法是什么?
假设我们想要一组按需计算的值(计算有一些副作用),并且在您再次访问它们时不再重新计算。
以下两种幼稚的方法是行不通的:
Prelude> let f x = print x >> return x
Prelude> let a = map f "abc"
Prelude> :t a
a :: [IO Char]
Prelude> head a
'a'
'a'
Prelude> head a
'a'
'a'
Run Code Online (Sandbox Code Playgroud)
Prelude> let b = mapM f "abc"
Prelude> :t b
b :: IO [Char]
Prelude> fmap head b
'a'
'b'
'c'
'a'
Prelude> fmap head b
'a'
'b'
'c'
'a'
Run Code Online (Sandbox Code Playgroud)
我该如何正确地做到这一点?到目前为止,我什至不明白集合应该有什么类型。
根据 Godbolt 的 Compiler Explorer(参见演示),以下代码使用 GCC(10.2 和主干)编译并输出 3628800,但无法使用 Clang(11.0.1 和主干)编译。在这两种情况下,-std=c++17都使用。它还可以使用 MSVC 19 进行编译,但不能使用其他编译器进行编译。为什么会这样,谁的行为是正确的?
#include <iostream>
int main()
{
std::cout << [](auto f) { return f(f); }(
[](auto& h) {
return [&h](auto n) {
if (n < 2)
return 1;
else
return n * h(h)(n - 1);
};
})(10) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
此外,即使GCC和MSVC拒绝的代码,如果我更换auto n用int n或如果我三元运算符替换的if-else( return n < 2 ? 1 : (n * h(h)(n - 1));)。