展开 Python 链表推导

Unroll Python chained list comprehension

我在在线书籍《数据挖掘程序员指南》(第 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 的帮助下完成,但在某处出错了。

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

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)
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)]

这样做是 select 数据中的 k 个随机点成为质心。

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

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

所以如果我们的数据中有 100 个项目并且 k 为 3,这将 return 列表 [0, 1, 2, ...99][=19] 中的 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)

希望对您有所帮助。