加快列表理解速度,替代方法?

时间:2020-10-26 08:28:03

标签: python performance numpy for-loop list-comprehension

在我的课堂上,我使用列表理解,这会花费太多时间。

class Crack:

    def __init__(self, filename):
    
        self._mesh = pyfrd.Mesh(filename)
        self._filename = filename
     
        self._node_sets = self._mesh.node_sets[1:]  # list of front names

        self._calc_crack_length()
               
    @property
    def nodes(self):
        return self._mesh.nodes.values      # return coordinates of the nodes

    def _calc_crack_length(self):
        """
        this method calculates the crack length for every node
    
        Parameters
        ----------
    
    
        Returns
        -------
        """
        scalc_time = time.time()
    
        # nodes on all fronts as sets
        nodes_fronts = [np.array(self.nodes[self._front_start(i) - 1 : self._front_end(i)])
                    for i in range(len(self._node_sets))]
    
        print(f"t2: {time.time() - scalc_time}")
    ...

self._node_sets是姓氏列表。 _front_start_front_end都返回一个节点号(前端的第一个/最后一个节点)。

有比列表理解更好的解决方案吗?

1 个答案:

答案 0 :(得分:0)

随着列表的建立,列表理解可能会分配和重新分配多次。由于您预先知道最终列表的长度(len(self._node_sets)),因此这可能是一个需要改进的地方。因此,您可以尝试将numpy数组的numpy数组替换为numpy数组列表。您将创建具有已知长度的numpy数组,然后使用与列表理解本身类似的循环来初始化该数组的元素。

nodes_fronts_arr = np.empty(shape=(len(self._node_sets),), dtype=np.object)
for i in range(len(self._node_sets)):
    nodes_fronts_arr[i] = np.array(self.nodes[self._front_start(i) - 1 : self._front_end(i)])

注意: 如果在上面的代码中将nodes_front_arr创建为2D数组,则可能会进一步改进。但是,只有每个内部数组的长度相同时,这才有意义。不管是不是,目前的问题细节中都没有提及。