我想构建一个函数,该函数可以返回六个“ R”字母加上六个“ B”字母的最常见排列,列表可能如下所示:
a = ['R'] * 6 + ['B'] * 6
random.shuffle(a)
shuffle = ''.join(a)
shuffle
输出:“ BRBRRRBBRBBR”
我想编写一个此函数的循环来模拟这些字符串的最常见分布。我确实用python写了一个for循环,它确实起作用了,但是在导入cython来加速该功能后,出了点问题,这是代码:
'''Python Code'''
import random
def random_loop_py(times):
a = ['R'] * 6 + ['B'] * 6
count = {}
for i in range(times):
random.shuffle(a)
shuffle = ''.join(a)
if shuffle in count.keys():
count[shuffle] += 1
else:
count[shuffle] = 1
return count
%timeit random_loop_py(100000)
'''Cython Code'''
%load_ext cython
%%cython
import random
cpdef void random_loop(int size):
a = ['R'] * 6 + ['B'] * 6
count = {}
for i in range(size):
random.shuffle(a)
shuffle = ''.join(a)
if shuffle in count.keys():
count[shuffle] += 1
else:
count[shuffle] = 1
return count.values()
错误:
Error compiling Cython file:
------------------------------------------------------------
...
shuffle = ''.join(a)
if shuffle in count.keys():
count[shuffle] += 1
else:
count[shuffle] = 1
return count.keys()
^
------------------------------------------------------------
/Users/lee_excited/.ipython/cython/_cython_magic_e70ad62499224c5d4fd4e23d6dcb9e49.pyx:12:21: Return with value in void function
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-120-a09f2e5d5e69> in <module>
----> 1 get_ipython().run_cell_magic('cython', '', "import random\ncpdef void random_loop(int size):\n a = ['R'] * 6 + ['B'] * 6\n count = {}\n for i in range(size):\n random.shuffle(a)\n shuffle = ''.join(a)\n if shuffle in count.keys():\n count[shuffle] += 1\n else:\n count[shuffle] = 1\n return count.keys()\n")
~/anaconda3/lib/python3.6/site-packages/IPython/core/interactiveshell.py in run_cell_magic(self, magic_name, line, cell)
2321 magic_arg_s = self.var_expand(line, stack_depth)
2322 with self.builtin_trap:
-> 2323 result = fn(magic_arg_s, cell)
2324 return result
2325
<decorator-gen-127> in cython(self, line, cell)
~/anaconda3/lib/python3.6/site-packages/IPython/core/magic.py in <lambda>(f, *a, **k)
185 # but it's overkill for just that one bit of state.
186 def magic_deco(arg):
--> 187 call = lambda f, *a, **k: f(*a, **k)
188
189 if callable(arg):
~/anaconda3/lib/python3.6/site-packages/Cython/Build/IpythonMagic.py in cython(self, line, cell)
323 if need_cythonize:
324 extensions = self._cythonize(module_name, code, lib_dir, args, quiet=args.quiet)
--> 325 assert len(extensions) == 1
326 extension = extensions[0]
327 self._code_cache[key] = module_name
TypeError: object of type 'NoneType' has no len()
请问我应该返回什么样的数据来加快仿真速度?
答案 0 :(得分:0)
您的函数具有void
返回类型:
cpdef void random_loop(int size):
...
return count.values()
因此,您不应从中返回任何内容,并且异常消息非常清楚。将返回类型更改为list
:
cpdef list random_loop(int size):
...
return list(count.values())
P.S。
您的功能不是非常适合Cython:我认为您不会获得显着的性能改善。
更新
修复后,我无法重现您的错误
In [9]: %%cython
...: import random
...: cpdef list random_loop(int size):
...: a = ['R'] * 6 + ['B'] * 6
...: count = {}
...: for i in range(size):
...: random.shuffle(a)
...: shuffle = ''.join(a)
...: if shuffle in count.keys():
...: count[shuffle] += 1
...: else:
...: count[shuffle] = 1
...: return list(count.values())
...:
In [10]: random_loop(10)
Out[10]: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
如您所见,它可以完美编译。