我对Python比较陌生,想知道我是在重新发明轮子还是用非pythonic方式做事 - 读错了.
我正在重写一些最初用Lua编写的解析器.有一个函数接受来自导入表及其值的字段名称,对值执行一些操作并将其存储在适当的键名下的目标字典中.
在原始代码中,它通过类似开关的语句解决,匿名函数作为操作.Python代码如下所示:
class TransformTable:
target_dict = {}
...
def mapfield(self, fieldname, value):
try:
{
'productid': self.fn_prodid,
'name': self.fn_name,
'description': self.fn_desc,
...
}[fieldname](value)
except KeyError:
sys.stderr.write('Unknown key !\n')
def fn_name(val):
validity_check(val)
target_dict['Product'] = val.strip().capitalize()
...
Run Code Online (Sandbox Code Playgroud)
当然,每个"字段处理程序"函数都会执行不同的操作并存储在target_dict中的不同键中.因为Python不支持带语句的匿名函数(或者我错过了什么?)函数必须单独编写,这些函数的代码可读性较低且不必要地复杂.
任何提示如何以更优雅和更pythonic的方式执行此类任务是值得赞赏的.
谢谢
大卫
我需要在非gui模式下重新定义Vim的键盘映射.
我根本不明白为什么以下命令不起作用:
:set <M-F5>=^[[15~
"E518: Unknown option: <M-F5>=^[[15~"
Run Code Online (Sandbox Code Playgroud)
而单独F5键或Meta与非功能键的映射确实有效:
:set <F5>=^[[15~
"ok"
:set <M-space>=^[[15~
"ok"
Run Code Online (Sandbox Code Playgroud)
如何用Vim中的功能键F1-F12重新定义Alt/Meta?
Thx提前.
大卫
更新:问题更 正在我的.vimrc中,我有以下键组合映射
autocmd Filetype python noremap <buffer> <silent> <M-F9> :w !pylint -E %<CR>
Run Code Online (Sandbox Code Playgroud)
但它只适用于gVim.遗憾的是,它不适用于非gui版本的Vim,因为Vim接收转义序列"^ [[20~"而不是直接的Meta-F9键码.
如果我需要获取包含内存密集元素的大型列表的值,我对GHC抛出堆栈溢出感到有些惊讶.我确实预计GHC有TCO,所以我永远不会遇到这种情况.
为了最简化这个案例,请看下面返回Fibonacci数的函数的简单实现(取自HaskellWiki).目标是显示百万分之一的数字.
import Data.List
# elegant recursive definition
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
# a bit tricky using unfoldr from Data.List
fibs' = unfoldr (\(a,b) -> Just (a,(b,a+b))) (0,1)
# version using iterate
fibs'' = map fst $ iterate (\(a,b) -> (b,a+b)) (0,1)
# calculate number by definition
fib_at 0 = 0
fib_at 1 = 1
fib_at n = fib_at (n-1) + fib_at (n-2)
main = do
{-- All following expressions abort with
Stack …
Run Code Online (Sandbox Code Playgroud) zipWith功能有两个严格的版本:
1)非常严格,列表l1和l2的元素得到评估,因此他们的thunk不会占用所有堆栈空间(Don Stewart代码)
zipWith' f l1 l2 = [ f e1 e2 | (e1, e2) <- zipWith k l1 l2 ]
where
k x y = x `seq` y `seq` (x,y)
Run Code Online (Sandbox Code Playgroud)
2)不是很严格,试图通过其他方式强制评估.
zipWith'' f l1 l2 = [ f e1 e2 | (e1, e2) <- zip (map (\x -> x `seq` x) l1) (map (\x -> x `seq` x) l2) ]
Run Code Online (Sandbox Code Playgroud)
问题是:为什么使用map的第二个例子的等效代码不会使函数也严格?
只是好奇如何重写以下函数只在程序的生命周期中调用一次?
getHeader :: FilePath -> IO String
getHeader fn = readFile fn >>= return . take 13
Run Code Online (Sandbox Code Playgroud)
上述功能从各种功能中被多次调用.如果使用相同的参数调用函数,如何防止重新打开文件,即.文件名 ?
试图了解最终签名是如何推断出来的:
GHCi> :t (+)
(+) :: Num a => a -> a -> a
GHCi> :t (<*>)
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
GHCi> :t (<*>) (+)
(<*>) (+) :: Num b => (b -> b) -> b -> b
Run Code Online (Sandbox Code Playgroud)
(a' -> a' -> a')
必须统一f (a -> b)
,所以f
可能是类型((->) r)
:
(<*>) :: Applicative ((->) r) => r -> (a -> b) -> (r -> a) …
Run Code Online (Sandbox Code Playgroud) 我正在寻找关于在内存中保存CSV(逗号分隔值)表的最合适的数据结构的建议.它应该涵盖两种情况:带有和没有标题的表.如果表包含标题,则所有行的所有字段都由key-> value对确定,其中key是标题中的名称,value是字段的适当内容.如果表不包含标题,则行只是字符串列表或者生成键名的key-> value对(如'COL1','COL2',...'COLn').
我正在寻找最简单(更少代码)和最通用的解决方案.
我正在考虑以下子类,但怀疑它是否是正确/有效的实现方式:
TCSV = class (TObjectList<TDictionary<string, string>>)
...
public
constructor Create(fileName: string; header: Boolean; encoding: string = '';
delimiter: Char = ';'; quoteChar: Char = '"'); overload;
...
end;
Run Code Online (Sandbox Code Playgroud)
看起来我必须为每一行字段保留密钥.怎么样TDictionary<string, TStringList>
?这会是一个更好的解决方案吗?
从*nix世界来看,我对Windows行为和可能的安全系统非常困惑.
我只是想在我的应用程序中执行外部程序.我发现WinAPI函数ShellExecute按预期工作,除非启动%windir%\ System32子目录中的某些程序.
执行ping.exe成功
ShellExecute(NULL, "open", "c:\\Windows\\System32\\ping.exe', NULL, NULL, SW_SHOW) );
// ^^^ OK, retcode == 42
Run Code Online (Sandbox Code Playgroud)执行java.exe失败
ShellExecute(NULL, "open", "c:\\Windows\\System32\\java.exe', NULL, NULL, SW_SHOW) );
// ^^^ ERROR_FILE_NOT_FOUND, retcode == 2
Run Code Online (Sandbox Code Playgroud)这很奇怪,因为java32确实存在于System32中,具有Users组的读/执行权限,可以从cmd调用.
C:\>dir /q c:\Windows\System32\java.exe
Volume in drive C has no label.
Volume Serial Number is 56E3-0868
Directory of c:\Windows\System32
11.01.2012 23:40 172 320 NT AUTHORITY\SYSTEM java.exe
1 File(s) 172 320 bytes
0 Dir(s) 226 127 564 800 bytes free
C:\>cacls c:\Windows\System32\java.exe
c:\Windows\System32\java.exe …
Run Code Online (Sandbox Code Playgroud) 只是好奇为什么以下代码无法在字符串表示中转换uint64值?
var
num: UInt64;
s: string;
err: Integer;
begin
s := '18446744073709551615'; // High(UInt64)
Val(s, num, err);
if err <> 0 then
raise Exception.Create('Failed to convert UInt64 at ' + IntToStr(err)); // returns 20
end.
Run Code Online (Sandbox Code Playgroud)
德尔福XE2
我在这里错过了什么吗?
通过任务,我们必须通过foldr实现foldl.通过比较函数签名和foldl实现,我提出了以下解决方案:
myFoldl :: (a -> b -> a) -> a -> [b] -> a
myFoldl _ acc [] = acc
myFoldl fn acc (x:xs) = foldr fn' (fn' x acc) xs
where
fn' = flip fn
Run Code Online (Sandbox Code Playgroud)
只需翻转函数参数以满足foldr期望类型,并通过递归应用传递函数来模拟foldl定义.令我惊讶的是,我的老师用零点评价了这个答案.
我甚至检查了这个定义,以与标准foldl相同的方式堆叠其中间结果:
> myFoldl (\a elm -> concat ["(",a,"+",elm,")"]) "" (map show [1..10])
> "((((((((((+1)+10)+9)+8)+7)+6)+5)+4)+3)+2)"
> foldl (\a elm -> concat ["(",a,"+",elm,")"]) "" (map show [1..10])
> "((((((((((+1)+10)+9)+8)+7)+6)+5)+4)+3)+2)"
Run Code Online (Sandbox Code Playgroud)
正确的答案是以下定义:
myFoldl :: (a -> b -> a) -> a -> [b] -> a
myFoldl f …
Run Code Online (Sandbox Code Playgroud) haskell ×5
delphi ×2
c ×1
c++ ×1
csv ×1
delphi-xe2 ×1
lua ×1
memory-leaks ×1
python ×1
strictness ×1
vim ×1
winapi ×1
windows ×1