Python:index()是否有缺陷?

Python:index()是否有缺陷?,python,indexing,Python,Indexing,我正在研究pyschools的这件事,这让我感到困惑。 代码如下: def convertVector(numbers): totes = [] for i in numbers: if i!= 0: totes.append((numbers.index(i),i)) return dict((totes)) 它应该以“稀疏向量”作为输入(例如:[1,0,1,0,2,0,1,0,0,1,0]) 并返回将非零项映射到其索引的dic

我正在研究pyschools的这件事,这让我感到困惑。 代码如下:

def convertVector(numbers):
    totes = []
    for i in numbers:
        if i!= 0:
            totes.append((numbers.index(i),i))
    return dict((totes))
它应该以“稀疏向量”作为输入(例如:
[1,0,1,0,2,0,1,0,0,1,0]
) 并返回将非零项映射到其索引的dict。 因此,具有
0:1
2:1
等的dict,其中
x
是列表中的非零项,
y
是其索引

因此,对于示例数字,它希望这样:
{0:1,9:1,2:1,4:2,6:1}
但是相反,它给了我这个:
{0:1,4:2}
(在它变成dict之前,它看起来是这样的:
[(0,1)、(0,1)、(4,2)、(0,1)、(0,1)]

我的计划是让
i
迭代
数字
,创建该数字及其索引的元组,然后将其转换为dict。代码似乎很简单,我不知所措。 在我看来,它就像是
数字。索引(i)
并没有返回索引,而是返回一些其他未预料到的数字

我对
index()
的理解是否有缺陷?是否存在已知的
index
问题? 有什么想法吗?

index()只返回第一个:

>>> a = [1,2,3,3]
>>> help(a.index)
Help on built-in function index:

index(...)
    L.index(value, [start, [stop]]) -> integer -- return first index of value.
    Raises ValueError if the value is not present.
如果您同时需要数字和索引,可以利用
枚举

>>> for i, n in enumerate([10,5,30]):
...     print i,n
... 
0 10
1 5
2 30
for index, item in enumerate(iterable):
  # blah blah
并适当修改您的代码:

def convertVector(numbers):
    totes = []
    for i, number in enumerate(numbers):
        if number != 0:
            totes.append((i, number))
    return dict((totes))
产生

>>> convertVector([1, 0, 1 , 0, 2, 0, 1, 0, 0, 1, 0])
{0: 1, 9: 1, 2: 1, 4: 2, 6: 1}

[虽然,正如有人指出的,虽然我现在找不到它,但编写
totes={}
并直接使用
totes[I]=number
分配给它比通过列表更容易。]

是您对
列表的理解不正确。索引
在列表中找到与参数相等的第一项的位置

要获取当前项的索引,您需要使用
enumerate
进行迭代:

>>> for i, n in enumerate([10,5,30]):
...     print i,n
... 
0 10
1 5
2 30
for index, item in enumerate(iterable):
  # blah blah
index()返回列表中项目的第一次出现的索引。列表中有重复项,这是造成混淆的原因。因此索引(1)将始终返回0。您不能期望它知道您要查找的是1的多个实例中的哪一个

我会这样写:

totes = {}
for i, num in enumerate(numbers):
     if num != 0:
          totes[i] = num
for index, value in enumerate(numbers):
    if value != 0:
        totes.append((index, value))
并且完全避免中间列表。

问题在于.index()查找某个参数的第一次出现。因此,对于您的示例,如果使用参数1运行它,它总是返回0

您可以像这样使用内置函数:

totes = {}
for i, num in enumerate(numbers):
     if num != 0:
          totes[i] = num
for index, value in enumerate(numbers):
    if value != 0:
        totes.append((index, value))


您想做的事情可以用一行完成:

>>> dict((index,num) for index,num in enumerate(numbers) if num != 0)
{0: 1, 2: 1, 4: 2, 6: 1, 9: 1}
检查:

返回值为x的第一项列表中的索引。它是 如果没有这样的项,则为错误

根据此定义,以下代码为
numbers
中的每个值附加一个元组,该元组由值和该值在整个列表中的第一个位置组成

totes = []
for i in numbers:
    if i!= 0:
        totes.append((numbers.index(i),i))
totes
列表中的结果是正确的:
[(0,1)、(0,1)、(4,2)、(0,1)、(0,1)]

当再次将其转换为时,结果是正确的,因为对于每个可能的值,您可以获得其在原始列表中第一次出现的位置

您可以使用
i
作为索引来获得所需的结果:

result = {}
for i in range(len(numbers)):
    if numbers[i] != 0:
        result[i] = numbers[i]
在@DSM上进行复刻:

def convertVector(numbers):
    return dict((i, number) for i, number in enumerate(numbers) if number)

或者,在重读时,正如@Rik Poggi实际建议的那样。

99.99999%的时候,如果你认为这是语言实现中的一个错误,那实际上是你的错。99.9%的统计数据是当场编造的!!谢谢,这肯定很有帮助。我不确定我到底理解了什么,但这是需要啃的东西。非常感谢。好的,是的,尽管我实际上,它在调用时返回第一个实例,而不是我想要的。这很有意义(尽管我现在认为索引可能是垃圾),多亏了你们两个。索引只是垃圾,如果你想让它做一些它不是为之设计的事。它根本不能做你想让它做的事。没有一个函数可以做到这一点。@DSM:当然!谢谢。(我认为使用
enumerate
的其他建议解决方案可能会更好,如果
enumerate
本身不清楚,这可能会“更清晰”)+1感谢我写下我所做的。嗯,在我写之前。也许我应该先阅读其他答案。