我在cython(python 2.7)上进行编码,并且我正在处理'对于'周期。只要我使用标准for i in range(N)
,我就会得到一个很酷的代码:在cythonized code.html
上没有黄色警告。
当我创建一个整数列表时(因为范围(N)是,isn'它?),例如:
cdef long [:] lista = np.array(list(nx.node_connected_component(Graph, v)))
它给出了图v
中Graph
的连通分量中节点的所有索引的列表。当我尝试定义for i in lista:
时,我收到了黄色警告:
__pyx_t_1 = __pyx_memoryview_fromslice(__pyx_v_lista, 1, (PyObject *(*)(char *)) __pyx_memview_get_long, (int (*)(char *, PyObject *)) __pyx_memview_set_long, 0);; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 151, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (likely(PyList_CheckExact(__pyx_t_1)) || PyTuple_CheckExact(__pyx_t_1)) {
__pyx_t_6 = __pyx_t_1; __Pyx_INCREF(__pyx_t_6); __pyx_t_15 = 0;
__pyx_t_17 = NULL;
} else {
__pyx_t_15 = -1; __pyx_t_6 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 151, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_6);
__pyx_t_17 = Py_TYPE(__pyx_t_6)->tp_iternext; if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 151, __pyx_L1_error)
}
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
for (;;) {
if (likely(!__pyx_t_17)) {
if (likely(PyList_CheckExact(__pyx_t_6))) {
if (__pyx_t_15 >= PyList_GET_SIZE(__pyx_t_6)) break;
#if CYTHON_COMPILING_IN_CPYTHON
__pyx_t_1 = PyList_GET_ITEM(__pyx_t_6, __pyx_t_15); __Pyx_INCREF(__pyx_t_1); __pyx_t_15++; if (unlikely(0 < 0)) __PYX_ERR(0, 151, __pyx_L1_error)
#else
__pyx_t_1 = PySequence_ITEM(__pyx_t_6, __pyx_t_15); __pyx_t_15++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 151, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
#endif
} else {
if (__pyx_t_15 >= PyTuple_GET_SIZE(__pyx_t_6)) break;
#if CYTHON_COMPILING_IN_CPYTHON
__pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_6, __pyx_t_15); __Pyx_INCREF(__pyx_t_1); __pyx_t_15++; if (unlikely(0 < 0)) __PYX_ERR(0, 151, __pyx_L1_error)
#else
__pyx_t_1 = PySequence_ITEM(__pyx_t_6, __pyx_t_15); __pyx_t_15++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 151, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
#endif
}
} else {
__pyx_t_1 = __pyx_t_17(__pyx_t_6);
if (unlikely(!__pyx_t_1)) {
PyObject* exc_type = PyErr_Occurred();
if (exc_type) {
if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
else __PYX_ERR(0, 151, __pyx_L1_error)
}
break;
}
__Pyx_GOTREF(__pyx_t_1);
}
__pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 151, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_v_i = __pyx_t_2;
/* … */
}
__Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
代码显然有效,但是,由于我需要经常使用这些循环,现在我想如何正确实现它们。
lista
的正确作业是什么?
答案 0 :(得分:0)
你最好只通过索引
循环它cdef Py_ssize_t i
cdef long val
with cython.boundscheck(False): # these two lines are optional but may increase speed
with cython.wraparound(False):
for i in range(lista.shape[0]):
val = lista[i]
您可能做的另一项优化是将lista
定义为
cdef long [::1] lista
表明它在记忆中是连续的。
(我对这个问题的初步解读让我觉得这是关于set
:np.array(list(nx.node_connected_component(Graph, v)))
的转换。我不认为这是你所要求的,但万一是的,我看不出加速这条线的方法。)