【问题标题】:Unroll Python chained list comprehension展开 Python 链表理解
【发布时间】:2015-02-28 12:30:45
【问题描述】:

我在在线书籍 A Programmer's Guide to Data Mining(第 8 章)中遇到了以下链表理解代码,这有点令人困惑。

第一个例子:

self.centroids = [[self.data[i][r]  for i in range(1, len(self.data))]
                   for r in random.sample(range(len(self.data[0])), self.k)]

第二个例子:

self.centroids = [[sum([self.data[k][i] for i in range(len(self.data[0]))
                   if self.memberOf[i] == centroid])/members[centroid]
                   for k in range(1, len(self.data))]
                   for centroid in range(len(self.centroids))] 

我想要此代码的等效常规 for 循环语法(非列表理解)。我尝试在 Understanding Python List Comprehension equivalent 的帮助下完成,但在某个地方出错了。

【问题讨论】:

    标签: python list-comprehension


    【解决方案1】:
    self.centroids = [[self.data[i][r]  for i in range(1, len(self.data))]
            for r in random.sample(range(len(self.data[0])), self.k)]
    

    这样做是选择数据中的 k 个随机点作为质心。

    random.sample(range(len(self.data[0])), self.k)
    

    从列表中返回一个包含 k 个唯一随机元素的列表 [0, 1, 2, .... len(self.data[0]) -1]

    所以如果我们的数据中有 100 个项目并且 k 为 3,这将返回列表 [0, 1, 2, ...99] 中的 3 个随机项目的列表

    让我们称之为:

    c = random.sample(range(len(self.data[0])), self.k)
    

    然后我们会有类似的东西:

    self.centroids = []
    for r in c:
      tmp = []
      for i in range(1, len(self.data)):   # this is how many columns 
                                           #(attributes) each data instance has.
          tmp.append(self.data[i][r])
      self.centroids.append(tmp)
    

    因此,例如,假设我们的数据如下所示:

    self.data = 
     [['basketball', 'basketball', 'runner', 
       'gymnast', 'gymnast', 'basketball', 'runner']
      [70, 72, 67, 58, 57, 71, 70],
      [148, 165, 135, 87, 85, 143, 140]]
    

    我们的随机样本 c 是 [1, 3] 上面的代码将使

    self.centroids = [[72, 165], [58, 87]]
    

    你提到的下一个:

    self.centroids = [[sum([self.data[k][i] for i in range(len(self.data[0]))
                   if self.memberOf[i] == centroid])/members[centroid]
                   for k in range(1, len(self.data))]
                   for centroid in range(len(self.centroids))] 
    

    这个是这样的:

    tmpCentroids = []
    for centroid in range(len(self.centroids)):  # so for each centroid 
       tmpCentroid = []
       for k in range(1, len(self.data)):        # and for each column (attribute) in the data
         total = 0
         for i in range (len(self.data[0])):     # for each data instance 
           if self.memberOf[i] == centroid       # if that instance is a member of that centroid group
              total += self.data[k][i]           # add that instances column value to the column total
         tmpCentroid.append(total/members[centroid])  # compute the avg. column value for that group
       tmpCentroids.append(tmpCentroid)
    

    希望对您有所帮助。

    【讨论】:

    • 谢谢,罗恩。作为最后一步,我们必须将 self.centroids 分配给 tmpCentroids。它有效。
    【解决方案2】:

    如果我没记错的话,第一个例子等价于

    self.centroids=[]
    for r in random.sample(range(len(self.data[0])),self.k):
        list_inner=[]
        for i in range(1, len(self.data)):
            list_inner.append(self.data[i][r])
        self.centroids.append(list_inner)
    

    你可以用同样的方法展开第二个。

    编辑:同样,没有办法真正测试这个,但第二个应该是:

    self.centroids = []
    for centroid in range(len(self.centroids)):
        middle = []
        for k in range(1, len(self.data)):
            inner = []
            for i in range(len(self.data[0])):
                if self.memberOf[i] == centroid:
                    inner.append(self.data[k][i])
            middle.append(sum(inner)/members[centroid])
        self.centroids.append(middle)
    

    【讨论】:

    • 从外到内展开适用于具有多个 for 循环的单个列表。列表中的列表不一样吗?具体来说,for循环(带有random.sample调用)应该是外循环还是内循环?第二个例子是更复杂的例子,我错了。
    • 您的代码看起来基本没问题,但缺少几个 )s。
    • 谢谢,现在应该修好了。
    • 第二个例子我仍然需要帮助,我更像是一个 Java / Ruby 程序员。成员[质心]对求和和除法的调用是我出错的地方。 ` self.centroids = [] for centroid in range(len(self.centroids)): list_first_inner=[] for k in range(1, len(self.data)): list_second_inner=[] for i in range(len( self.data[0])): if self.memberOf[i] == centroid:` 在这之后会发生什么?我尝试了各种方法,但出现错误。
    • self.centroids = [] for centroid in range(len(self.centroids)): list_first_inner=[] for k in range(1, len(self.data)): list_second_inner=[] for i in range(len(self.data[0])): if self.memberOf[i] == centroid:
    猜你喜欢
    • 1970-01-01
    • 2013-05-03
    • 2016-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-01
    • 2022-11-02
    • 2019-06-25
    相关资源
    最近更新 更多