【问题标题】:First items in inner list efficiently as possible [duplicate]内部列表中的第一项尽可能有效地[重复]
【发布时间】:2012-10-16 13:59:25
【问题描述】:

我在 python A[row,col,value] 中有一个协调的存储列表,用于存储非零值。

如何获取所有行索引的列表?我希望这个A[0:][0] 能够像print A[0:] 打印整个列表但print A[0:][0] 只打印A[0]

我问的原因是为了有效计算每行中非零值的数量迭代range(0,n),其中n是总行数。这应该比我目前的for i in range(0,n): for j in A: ... 方式便宜

类似:

c = []
# for the total number of rows
for i in range(0,n):
     # get number of rows with only one entry in coordinate storage list
     if A[0:][0].count(i) == 1: c.append(i)                
return c

结束:

c = []
# for the total number of rows 
for i in range(0,n):
    # get the index and initialize the count to 0 
    c.append([i,0])
    # for every entry in coordinate storage list 
    for j in A:
        # if row index (A[:][0]) is equal to current row i, increment count  
        if j[0] == i:
           c[i][1]+=1
return c

编辑:

使用 Junuxx 的答案 this questionthis post 我想出了以下 (用于返回单例行数) 对于我当前的问题大小 A 来说,这比我最初的尝试。然而,它仍然随着行数和列数的增加而增长。我想知道是否有可能不必遍历A,而只需遍历n

# get total list of row indexes from coordinate storage list
row_indexes = [i[0] for i in A]
# create dictionary {index:count}
c = Counter(row_indexes)    
# return only value where count == 1 
return [c[0] for c in c.items() if c[1] == 1]

【问题讨论】:

  • @larsman:我假设 A 是三元组列表。
  • 你能写一个简单、低效、有效的例子来说明你正在尝试做什么吗?我发现问题的措辞确实令人困惑,而且您的示例代码块似乎都没有做同样的事情..?
  • 我正在计算坐标存储列表中仅包含 1 个非零值的所有行。只有第二个代码块略有不同,因为它返回了每一行的计数。我已经用 cmets 更新了代码。

标签: python list optimization performance


【解决方案1】:

应该这样做:

c = [x[0] for x in A]

这是一个列表推导式,它采用A 的每个元素的第一个(子)元素。

【讨论】:

  • 这比我原来的解决方案好得多。请查看我的编辑,是否可以不迭代 A ?非常感谢!
  • 如果 A 非常大,但 A 的元素只有三个成员,那么存储三个列表可能更有效,rowscolumnsvalues。您将能够立即获取所有行号,并且仍然可以通过对所有三个列表(它们是对齐的)使用相同的索引来访问单个条目。如果 A 和子列表都很长,最好使用真正的二维数据结构,例如 numpy 提供的(参见 Jon Clements 的回答),而不是嵌套列表。
【解决方案2】:

为了提高效率和扩展切片,您可以使用numpy - 鉴于您的示例,这似乎是个好主意:

import numpy as np
yourlist = [
    [0, 0, 0],
    [0, 1, 1],
    [1, 0, 2]
]
a = np.array(yourlist)
print a[:,0]
# [0 0 1]
bc = np.bincount(a[:,0])
# array([2, 1])
count = bc[bc==1].size
# 1
# or... (I think it's probably better...)
count = np.count_nonzero(bc == 1)

【讨论】:

  • 我无法让您的示例起作用..type(mylist[0][0]) 返回inttype(a[0][0])a = numpy.array(mylist) 之后返回numpy.float64 当我尝试bincount(a[:,0]) 时我得到TypeError: array cannot be safely cast to required type 我试过bc = numpy.bincount(numpy.arange( a[:,0],dtype=numpy.int)),错误是TypeError: only length-1 arrays can be converted to Python scalars
  • @sudo_o 不知道该说什么 - 在np.array(不是np.arange)之后我得到type(a[0][0]) 其他一切都正常.. .
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-09
  • 1970-01-01
  • 2020-03-14
  • 1970-01-01
  • 2016-11-17
  • 2022-01-07
  • 1970-01-01
相关资源
最近更新 更多