- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我一直在使用 Python timeit模块很长一段时间,但它只是通过交互式 Python session 或 Unix shell。现在,我尝试在 Windows 命令提示符 (cmd.exe) 中测量一些代码片段,但它显示此错误:
C:\Users\Me>python -m timeit '"-".join(map(str, range(100)))'
Traceback (most recent call last):
File "C:\Python33\lib\runpy.py", line 160, in _run_module_as_main
"__main__", fname, loader, pkg_name)
File "C:\Python33\lib\runpy.py", line 73, in _run_code
exec(code, run_globals)
File "C:\Python33\lib\timeit.py", line 334, in <module>
sys.exit(main())
File "C:\Python33\lib\timeit.py", line 298, in main
t = Timer(stmt, setup, timer)
File "C:\Python33\lib\timeit.py", line 131, in __init__
code = compile(src, dummy_src_name, "exec")
File "<timeit-src>", line 6
'-.join(map(str,
^
SyntaxError: EOL while scanning string literal
这相当令人困惑,因为我没有在字符串中插入任何换行符 - 相反,我实际上直接从 timeit 模块文档中粘贴了示例。
在玩这个的时候,我尝试测试没有任何空格的片段,因为错误标记的字符就在它们之前。即使现在没有发生异常,该模块报告的执行时间也与我传递了一个 pass
语句一样,如下所示:
C:\Users\Me>python -m timeit
100000000 loops, best of 3: 0.013 usec per loop
C:\Users\Me>python -m timeit 'map(str,range(100))'
100000000 loops, best of 3: 0.013 usec per loop
C:\Users\Me>python -m timeit 'map(str,range(1000000000000000))'
100000000 loops, best of 3: 0.013 usec per loop
我确信我正确地调用了模块,因为我在 Unix shell 上粘贴了相同的行并且它们按预期工作。
因为我用 Python 2.7 和 3.3 得到了完全相同的结果(另外,该模块是用纯 Python 编写的,并且已经存在很长时间了)我确信这与 Python 无关,但 Windows相反,命令提示符。
那么,为什么会发生这种奇怪的行为,我该如何解决呢?
最佳答案
对传递给 timeit 模块的语句使用双引号。
示例:
C:\Users\Me>python -m timeit "'-'.join(map(str, range(100)))"
10 loops, best of 3: 28.9 usec per loop
与 bash 和 tcsh 等 Unix shell 相比,单引号在 Windows 命令行中的处理方式不同。
这里有一个小的 python 程序来演示这一点:
import sys
print(sys.argv[1:])
运行它(我们称文件为 cmdtest.py),我们观察到以下内容:
C:\Users\Me\Desktop>python cmdtest.py 1 2 3
['1', '2', '3']
C:\Users\Me\Desktop>python cmdtest.py "1 2 3"
['1 2 3']
C:\Users\Me\Desktop>python cmdtest.py '1 2 3'
["'1", '2', "3'"]
因此,单引号按字面意思处理(即不作为特殊字符)。在 SO 中搜索了一下,我找到了 this great description of argument tokenization by cmd :
When invoking a command from a command window, tokenization of the command line arguments is not done by
cmd.exe
(a.k.a. "the shell"). Most often the tokenization is done by the newly formed processes' C/C++ runtime, but this is not necessarily so -- for example, if the new process was not written in C/C++, or if the new process chooses to ignoreargv
and process the raw commandline for itself (e.g. with [GetCommandLine()][1]). At the OS level, Windows passes command lines untokenized as a single string to new processes. This is in contrast to most *nix shells, where the shell tokenizes arguments in a consistent, predictable way before passing them to the newly formed process. All this means that you may experience wildly divergent argument tokenization behavior across different programs on Windows, as individual programs often take argument tokenization into their own hands.If it sounds like anarchy, it kind of is. However, since a large number of Windows programs do utilize the Microsoft C/C++ runtime's
argv
, it may be generally useful to understand how the MSVCRT tokenizes arguments. Here is an excerpt:
- Arguments are delimited by white space, which is either a space or a tab.
- A string surrounded by double quotation marks is interpreted as a single argument, regardless of white space contained within. A quoted string can be embedded in an argument. Note that the caret (^) is not recognized as an escape character or delimiter.
考虑到上述情况,让我们首先解释第二个奇怪的行为(充当 pass
语句的行为),因为它更简单一些。由于单引号按字面解释,调用时:
C:\Users\Me>python -m timeit 'map(str,range(100))'
确切的字符串文字 'map(str,range(100))'
(包含引号)作为语句传递给时间。
所以,Python 会看到
"'map(str,range(100))'"
代替
'map(str,range(100))'
作为一个字符串,它实际上并没有做任何事情,并且给出了非常接近于 pass
语句的测量值。
现在第一个错误:
正如为 python timeit 所记录的那样模块:
A multi-line statement may be given by specifying each line as a separate statement argument;
所以,调用时:
C:\Users\Me>python -m timeit '"-".join(map(str, range(100)))'
Python 看到 ["'-.join(map(str,", "range(100)))'"]
作为语句传递给 timeit,模块将其解释为多行声明:
'"-".join(map(str,
range(100)))'
它的第一行是一个字符串,它以单引号开头,但从不关闭,因此(最终)解释了奇怪的 EOL 错误。
对时间语句使用双引号可以解决问题。
我也尝试过 Windows PowerShell,它比 cmd.exe 更高级,并且表现出与 Unix shell 类似的行为,但并没有完全解决所有问题我测试的语句。
例如,这是可行的(注意语句中的空格):
PS C:\Users\Me> python -m timeit 'map(str, range(100))'
1000000 loops, best of 3: 0.688 usec per loop
虽然最初的例子没有:
PS C:\Users\Me\Desktop> python -m timeit '"-".join(map(str, range(100)))'
option -. not recognized
use -h/--help for command line help
(不过,我还不是很满意。我宁愿做的是让 cmd 或 PowerShell 像 Unix shell 一样工作,这样我就可以简单地粘贴和时间代码片段。如果有人知道一种快速而肮脏的方法来完成此操作(如果可能的话),以完成答案,那就太棒了。)
关于Python timeit命令行错误: "SyntaxError: EOL while scanning string literal",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23987208/
我正在使用 timeit.timeit 函数来计时我自己的函数之一,但返回的时间是科学计数法。 import timeit def func(): ... print(timeit.timei
我正在尝试编写一个简单的时间装饰器来测量函数所花费的时间。但是下面的代码给出了我们的递归错误。有什么问题吗? import timeit def measure(func): def wrap
import timeit t=timeit.timeit('x=map(lambda x:x*10,range(32))') print(t) 这表现了: 0.4678139 但 t=timeit.
我一直在尝试执行一个代码片段来了解执行需要多长时间。我尝试了两种选择来做到这一点。一种是在 timeit.timeit 函数内使用变量并进行检查。另一种是直接使用值并检查。第二种方法工作正常,但我在使
假设我有一些函数接受一个数组并将每个元素更改为 0。 def function(array): for i in range(0,len(array)): array[i] =
有没有办法在 python 中为 timeit.timeit() 函数指定拆卸?我知道有关于“声明”和“设置”的争论,但我还没有找到执行拆卸的好方法。 在我的“声明”中包含拆解代码会影响我尝试计时的代
有时,我喜欢计算我的部分代码运行需要多长时间。我检查了很多在线网站,并且看到了两种主要的方法来做到这一点。一种是使用time.time,另一种是使用timeit.timeit。 所以,我写了一个非常简
我想从 python timeit 模块检查打印以下内容需要多少时间,如何打印, import timeit x = [x for x in range(10000)] timeit.timeit("
我在 Project Euler 上工作过问题并决定添加计时,因此通过以下代码段将 timeit 添加到时间 main()(将全局 RESULT 存储在 main( ) 为了方便起见) t = tim
当我执行 help('timeit') 时,位于 timeit 模块(Python(2.7) 标准库)中的以下函数不会显示。 def reindent(src, indent): """Hel
考虑这段 Python3 代码: def classic_fibonacci(limit: int) -> List[int]: nums = [] curr, nxt = 0, 1
令人惊讶的 ipython 魔法 %timeit 错误: In[1]: a = 2 In[2]: %timeit a = 2 * a Traceback (most recent call last)
我有一个函数 f(x),它将 0 和 1 之间的 100 个随机 float 的列表 x 作为输入。不同的列表将导致不同的运行时间f. 我想知道 f 在大量不同的随机列表上平均运行多长时间。最好的方法
我想检查在合并 2 个数据帧时使用数字查找值是否比使用字符串查找值更快。为此,我将 %timeit 与以下代码一起使用: 合并字符串查找值: %timeit newframe = subframe.m
我正在计时从 python set 和 list 中删除元素。我的列表 timeit 代码引发了 ValueError: ... x not in list,但仅当我使用 timeit 运行不止一次迭
我想以便宜的方式测量函数的执行时间,如下所示: def my_timeit(func, *args, **kwargs): t0 = time.time() result = func
我想在 Python 3.5 中使用 timeit 来测量两个函数。第一个依赖于 import math,第二个依赖于 from math import log2。虽然我可以通过在调用 timeit.
更新:显然我只是在计时 Python 读取列表的速度。但这并没有真正改变我的问题。 所以,我前几天读了 this post 并想比较一下速度。我对 Pandas 还不熟悉,所以每当我看到有机会做一些比
假设这样一个数据 In [51]: data = list(range(10**6))
谁能解释一下为什么会这样? aatiis@aiur ~ $ time python /usr/lib64/python2.7/timeit.py -n 1 \ -- 'x = 10**1000
我是一名优秀的程序员,十分优秀!