【问题标题】:Speed up list comprehension, alternative?加快列表理解,替代方案?
【发布时间】:2021-02-08 12:08:14
【问题描述】:

在我的课堂上,我使用了一个需要太多时间的列表理解。

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 都返回一个节点号(前端的第一个/最后一个节点)。

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

【问题讨论】:

  • 如果你有很多数据,需要很长时间。你到底想做什么?
  • 在这个列表理解中,我想创建一个数组列表。每个数组都包含其前面(裂缝)节点的所有坐标。

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


【解决方案1】:

随着列表的建立,列表推导式可能会多次分配和重新分配。由于您事先知道最终列表的长度 (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 被创建为二维数组,则可以进一步改进。但是,只有当每个内部数组都具有相同的长度时,这才有意义。是不是这样,目前问题详情中没有提到。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-11
    • 2012-07-05
    • 2012-01-23
    相关资源
    最近更新 更多