展开Python链式列表理解

时间:2015-02-28 12:30:45

标签: python 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的帮助下做,但在某个地方出错了。

2 个答案:

答案 0 :(得分:0)

如果我没弄错的话,第一个例子相当于

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)

答案 1 :(得分:0)

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,则会返回列表中的3个随机项目列表[0,1,2,... 99]

让我们称之为:

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)

希望有所帮助。