我正在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
遍历numbers
,创建一个包含该数字及其索引的元组,然后将其转换为dict。代码看起来很简单,我不知所措。在我看来,numbers.index(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.
如果你想要数字和索引,你可以利用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
分配它比通过列表更容易。]
您要做的事情,可以在一行中完成:
>>> dict((index,num) for index,num in enumerate(numbers) if num != 0)
{0: 1, 2: 1, 4: 2, 6: 1, 9: 1}
list.index
的理解是错误的。它查找列表中第一个项的位置,该项与参数进行比较。
要获得当前项目的索引,您需要使用enumerate
:进行迭代
for index, item in enumerate(iterable):
# blah blah
问题是.index()查找某个参数的第一个出现。因此,对于您的示例,如果您使用参数1运行它,它总是返回0。
您可以使用内置的枚举函数,如下所示:
for index, value in enumerate(numbers):
if value != 0:
totes.append((index, value))
检查文档中的索引:
返回值为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]
index()返回列表中项目的第一次出现的索引。您的列表有重复项,这是您感到困惑的原因。因此,索引(1)将始终返回0。你不能指望它知道你在寻找1的众多实例中的哪一个。
我会这样写:
totes = {}
for i, num in enumerate(numbers):
if num != 0:
totes[i] = num
并且完全避开中间列表。
在@DSM:上步枪射击
def convertVector(numbers):
return dict((i, number) for i, number in enumerate(numbers) if number)
或者,正如@Rik Poggi实际建议的那样,在重读时。