对 Python 列表语法感到困惑

Posted

技术标签:

【中文标题】对 Python 列表语法感到困惑【英文标题】:confused about Python list syntax 【发布时间】:2016-12-27 20:02:29 【问题描述】:

这是代码和相关文档(http://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_iris.html#sklearn.datasets.load_iris),我对这行感到困惑,data.target[[10, 25, 50]],困惑为什么要使用双精度[[]],如果有人能澄清一下,那就太好了。

from sklearn.datasets import load_iris
data = load_iris()
print data.target[[10, 25, 50]]
print list(data.target_names)

提前致谢, 林

【问题讨论】:

@TigerhawkT3 看起来[10, 25, 50] 正在从data.target 数组中编入索引 @TigerhawkT3,谢谢并投票。我试过print type(data.target),返回的是<type 'numpy.ndarray'>。困惑你的意思是包含单个元素的列表,你能帮忙详细说明一下吗?谢谢。 @cricket_007,谢谢并投票,但为什么要使用双 [[]] 你对 NumPy 数组感到困惑,而不是 Python 列表。 谢谢@cricket_007,投赞成票。那么[[10, 25, 50]]中的double [[]]是什么意思 【参考方案1】:

您的困惑是可以理解的:这无论如何都不是“标准”Python。

data.target 在这种情况下是来自 numpy 的 ndarray

In [1]: from sklearn.datasets import load_iris
   ...: data = load_iris()
   ...: print data.target[[10, 25, 50]]
   ...: print list(data.target_names)
[0 0 1]
['setosa', 'versicolor', 'virginica']

In [2]: print type(data.target)
<type 'numpy.ndarray'>

numpy 的 ndarray 实现允许您通过提供所需项目的索引列表来创建新数组。例如:

In [13]: data.target
Out[13]:
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])

In [14]: data.target[1]
Out[14]: 0

In [15]: data.target[[1,2,3]]
Out[15]: array([0, 0, 0])

In [16]: print type(data.target[[1,2,3]])
<type 'numpy.ndarray'>

这很可能是由overriding __getitem__ 完成的。

有关详细信息,请参阅 NumPy 数组文档中的 Indexing:

【讨论】:

感谢 Christian,为全面的回复投票,所以这意味着从 numpy 数组 data.target 中检索 10, 25, 50-th 元素并在 Python 中获得新列表?如果是这样,type(data.target[[10, 25, 50]]) 应该是一个正式的 Python 列表,对吗? @LinMa 看答案的最后一行代码,还是numpy.ndarray 谢谢@cricket_007,投赞成票。现在一切都清楚了。 :) 您可以在很多方面将numpy.ndarray 视为一个列表(对其进行迭代、切片等),但如果您要这样做,我强烈建议您阅读@987654324 @ 首先,因为有一些非标准行为可能会让您感到困惑。 感谢 Christian,投票并将您的回复标记为答案。【参考方案2】:

这是使用“整数索引”语法(与通常的下标相反)从 numpy 数组 A 中检索元素,即整数列表 B 将用于在 @987654323 中的特定索引处查找元素@。您的输出是一个 numpy 数组,其形状与您用作“输入”的列表 B 相同,并且输出元素的值是从这些整数索引处的 A 的值中获得的,例如:

>>> import numpy
>>> a = numpy.array([0,1,4,9,16,25,36,49,64,81])
>>> a[[1,4,4,1,5,6,6,5]]
  array([ 1, 16, 16,  1, 25, 36, 36, 25])

整数索引可以应用于多个维度,例如:

>>> b = numpy.array([[0,1,4,9,16],[25,36,49,64,81]]) # 2D array
>>> b[[0,1,0,1,1,0],[0,1,4,3,2,3]]   # row and column integer indices
  array([ 0, 36, 16, 64, 49,  9])

或者,同样的例子,但输入列表有 2 个维度,影响 输出 形状:

>>> b[[[0,1,0],[1,1,0]],[[0,1,4],[3,2,3]]] # "row" and "column" 2D integer arrays
  array([[ 0, 36, 16],
         [64, 49,  9]])

另请注意,您也可以使用 numpy 数组而不是列表来执行“整数索引”,例如

>>> a[numpy.array([0,3,2,4,1])]
  array([ 0,  9,  4, 16,  1])

【讨论】:

以上是关于对 Python 列表语法感到困惑的主要内容,如果未能解决你的问题,请参考以下文章

带有 lambda 的 Python 列表理解 [重复]

对桌子设计感到困惑。如何存储多个数据

对访问数组中的可变字典感到困惑

链表,对将节点添加到链表头部的函数感到困惑

python中的all()如何处理空列表

在 Joomla 替代布局和使用 K2 模板之间感到困惑