用元组索引的Python列表

3

我是一位Matlab用户,需要使用Python进行一些工作,希望有人可以帮助我理解Python语法:

(1) 在Python中,是否可以使用元组索引列表?如果可以,如何实现?例如,我想使用它来表示一组数据的矩阵。

(2) 假设我可以使用由元组索引的列表,比如data[(row,col)],我该如何删除整列数据?在Matlab中,我知道可以这样做:

 new_data = [data(:,1:x-1) data(:,x+1:end)];

如果我想从数据中删除x列,应该怎么做呢?

(3) 如何轻松地计算每行非负元素的数量。例如,在Matlab中,我可以这样做:

 sum(data>=0,1)

这将给我一个列向量,表示每行非负条目的数量。
非常感谢!

2
我不知道这是否有助于找到Python的等效操作,但是在MATLAB中也可以使用语法data(:,x) = [];删除矩阵中的整列。 - gnovice
1
谢谢大家!NumPy/SciPy正是我所需要的。它的语法与Matlab非常接近。再次感谢你们的帮助,我非常感激! - Shlomo Shmai
1
这不是很棒吗?如果你是Matlab用户,那么你会发现与Numpy/Scipy一起使用ipython绝对是必不可少的。面向对象编程,例如(data>=0).sum()或data.size或data.shape(),在我看来,使得Numpy/Scipy比Matlab更好。 - Steve Tjoa
8个回答

8
你应该了解一下numpy,它是专门为这种事情而设计的。

2
numpy会完成问题中要求的一切,语法几乎与matlab完全相同。 - Autoplectic
1
Numpy数组是最好的选择。我建议使用这个页面来帮助您更轻松地过渡- http://www.scipy.org/NumPy_for_Matlab_Users - Raja Selvaraj

3
  1. 不行,但字典可以。
  2. 听起来你想要一个“2D数组”,矩阵类型或其他什么东西。你看过numpy了吗?
  3. 取决于你从#2中选择了什么,但Python确实有sum和其他直接作用于可迭代对象的函数。看一下生成器表达式和列表推导式。例如:
row_count_of_non_neg = sum(1 for n in row if n >= 0)
# 或者:
row_count_of_non_neg = sum(n >= 0 for n in row)
# “滥用”True == 1和False == 0

2

以下是如何在numpy中轻松创建一个数组(矩阵)的示例:

>>> import numpy
>>> a = numpy.array([[1,2,3],[4,5,6],[7,8,9]])

这是它的显示方式。
>>> a
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

如何获取行或列:

>>> a[0,:]
array([1, 2, 3])
>>> a[:,0]
array([1, 4, 7])

希望这个例子能够清晰地表达语法!Numpy相当强大。


2
我同意大家的观点。使用Numpy/Scipy。但这里是针对你问题的具体答案。
1. 是的。索引可以是内置列表或Numpy数组。假设 x = scipy.array([10, 11, 12, 13])y = scipy.array([0, 2])。那么 x[[0, 2]]x[y] 都返回相同的结果。
2. new_data = scipy.delete(data, x, axis=0) 3. (data>=0).sum(axis=1) 注意:示例2展示了Numpy/Scipy的一个常见陷阱。如示例3所示,axis属性通常设置为0以沿着数组的第一维操作,设置为1以沿着第二维操作,依此类推。但是像delete这样的某些命令实际上会反转维度顺序,如示例2所示。你知道,行主序和列主序。

1
你可以通过重载内置列表的 __getitem__ 和 __setitem__ 方法来扩展列表功能,以允许使用元组进行索引。尝试以下代码:

class my_list(list):
    def __getitem__(self, key):
        if isinstance(key, tuple) and len(key) > 0:
            temp = []
            for k in key: temp.append(list.__getitem__(self, k))
            return temp
        else:
            return list.__getitem__(self, key)

    def __setitem__(self, key, data):
        if isinstance(key, tuple) and len(key) > 0:
            for k in key: list.__setitem__(self, k, data)
        else:
            list.__setitem__(self, key, data)


if __name__ == '__main__':
   L = my_list([1, 2, 3, 4, 5])
   T = (1,3)
   print(L[T]) 

0

使用原生Python,您可以使用以下代码:

my_list = [0, 1, 2, 3]
index_tuple = (1,2)
x = [item for idx, item in enumerate(my_list) if idx in index_tuple]

0

(1) 我认为你不能使用元组作为Python列表的索引。你可以使用列表的列表(例如a[i][j]),但这似乎不是你的重点。你可以使用一个键为元组的字典。

d = { (1,1):1, (2,1):2  ... } 

(2)如果您不在意性能,

map( lambda x: d.remove(x) if x[1] = col_number, d.keys() )

(3)你也可以使用过滤器来实现这一点。

sum(
map( lambda x:x[1], filter(lambda x,y: x[1] == row_num and y > 0, d.items()))
)

将map或filter与lambda结合使用会显得很笨拙,而使用生成器表达式则不然:sum(y for x, y in d.items() if x[1] == row_num and y > 0)(这个表达式应该等同于你的代码,但你的代码似乎有一个错误)。 - Roger Pate

0

不,列表只能通过整数进行索引,不能使用其他类型。然而,字典是另一种情况。字典是一个哈希表,由键值对组成。键必须是唯一且不可变的。值可以是任何类型的对象,包括整数、元组、列表或其他字典。对于您的示例,元组可以作为键,因为它们是不可变的。另一方面,列表不是不可变的,因此不能作为字典键。

您提出的一些功能可以通过字典和列表推导的组合来实现。其他功能则需要创建字典的子类并添加方法以实现所需的功能。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接