【问题标题】:Python: is index() buggy at all?Python:index() 有问题吗?
【发布时间】:2012-02-13 00:34:47
【问题描述】:

我正在 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]) 并返回一个将非零条目映射到其索引的字典。 所以一个带有0:12:1 等的字典,其中x 是列表中的非零项,y 是它的索引。

所以对于示例编号,它想要这样:{0: 1, 9: 1, 2: 1, 4: 2, 6: 1} 而是给了我这个:{0: 1, 4: 2}(在变成字典之前,它看起来像这样: [(0, 1), (0, 1), (4, 2), (0, 1), (0, 1)]

我的计划是让i 遍历numbers,创建该数字及其索引的元组,然后将其转换为字典。代码看起来很简单,我很茫然。 在我看来,numbers.index(i) 没有返回索引,而是返回了一些其他的、意想不到的数字。

我对@9​​87654333@的理解有问题吗?是否存在已知的index 问题? 有什么想法吗?

【问题讨论】:

  • 99.99999% 的情况下,如果您认为这是语言实现中的错误,那实际上是您的错。
  • 99.9%的统计数据都是现场制作的!!

标签: python indexing


【解决方案1】:

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.

如果你想要数字和索引,你可以利用enumerate

>>> for i, n in enumerate([10,5,30]):
...     print i,n
... 
0 10
1 5
2 30

并适当修改您的代码:

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 直接分配给它比通过列表更容易。]

【讨论】:

  • 谢谢,这绝对有帮助。不确定我是否完全理解,但它的一些东西要啃。非常感谢。
【解决方案2】:

你想要做的,可以在一行中完成:

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

【讨论】:

  • +1 写我所做的。呃,在我之前。也许我应该先阅读其他答案。
【解决方案3】:

是的,您对list.index 的理解不正确。它找到列表中与参数比较相等的 first 项的位置。

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

for index, item in enumerate(iterable):
  # blah blah

【讨论】:

    【解决方案4】:

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

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

    for index, value in enumerate(numbers):
        if value != 0:
            totes.append((index, value))
    

    【讨论】:

      【解决方案5】:

      查看documentation for index

      返回列表中第一个值为 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:当然!谢谢。 (我认为enumerate 的其他建议解决方案可能会更好,如果enumerate 本身不清楚,这可能会“更清楚”。)
      【解决方案6】:

      index() 返回列表中项目第一次 出现的索引。您的列表有重复,这是您感到困惑的原因。所以 index(1) 将始终返回 0。你不能指望它知道你在寻找 1 的众多实例中的哪一个。

      我会这样写:

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

      并完全避免中间列表。

      【讨论】:

      • 好的,所以虽然我前进了,但它在调用时返回第一个实例,而不是我想要的那个。这是有道理的(虽然我现在瘦索引晚上是废话)谢谢你们。
      • 索引只有在你想让它做一些不是为它设计的事情时才是废话。它根本无法做你想做的事。没有一个函数可以做到这一点。
      【解决方案7】:

      在@DSM 上翻唱:

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

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

      【讨论】:

        猜你喜欢
        • 2018-09-14
        • 2012-03-03
        • 2011-10-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-12
        相关资源
        最近更新 更多