如何获取项目在列表中的位置?


169

我正在遍历列表,如果满足特定条件,我想打印出该项目的索引。我该怎么做?

例:

testlist = [1,2,3,5,3,1,2,1,6]
for item in testlist:
    if item == 1:
        print position

Answers:


280

嗯 这里有一个关于列表理解的答案,但是它消失了。

这里:

 [i for i,x in enumerate(testlist) if x == 1]

例:

>>> testlist
[1, 2, 3, 5, 3, 1, 2, 1, 6]
>>> [i for i,x in enumerate(testlist) if x == 1]
[0, 5, 7]

更新:

好的,您需要一个生成器表达式,我们将有一个生成器表达式。再次在for循环中,这是列表理解:

>>> for i in [i for i,x in enumerate(testlist) if x == 1]:
...     print i
... 
0
5
7

现在我们将构建一个生成器...

>>> (i for i,x in enumerate(testlist) if x == 1)
<generator object at 0x6b508>
>>> for i in (i for i,x in enumerate(testlist) if x == 1):
...     print i
... 
0
5
7

令人高兴的是,我们可以将其分配给变量,然后从那里使用它...

>>> gen = (i for i,x in enumerate(testlist) if x == 1)
>>> for i in gen: print i
... 
0
5
7

并且以为我曾经写过FORTRAN。


6
经过大概25年的函数式编程质疑之后,我认为我终于找到了线索。清单理解力是炸弹。
查理·马丁

15
我认为您是指“单个字母”,并且坦率地说,在此示例中,较长的名称将没有更多的信息内容。
查理·马丁

2
感谢您的出色回答。我认为@nailer的注释可能与以下事实有关:在生成器示例中的一行中,您在两个不同的上下文中使用了“ i”;一个在理解内,另一个在其中进行迭代。我知道这让我离开了一秒钟。
布朗

1
@CharlieMartin您将“ i”用作索引,而不是根据单个字符变量的一种通用约定使用项目。命名索引“ index”和项目“ item”将消除歧义。另外,您要回复使用“项目”和“位置”的家长,这是一种很好的方式,不要在您的答案中不必要地重命名原始代码的某些部分。
mikemaccana

1
超级语法:o)您可以轻松获取命令行参数。让我们提供一系列参数:args = ['x', '-p1', 'v1', '-p2', 'v2']。然后命令args[[i for i, x in enumerate(args) if x == '-p1'][0] + 1]返回'v1'
Theodor Keinstein 2014年

170

接下来呢?

print testlist.index(element)

如果不确定要查找的元素是否确实在列表中,则可以添加初步检查,例如

if element in testlist:
    print testlist.index(element)

要么

print(testlist.index(element) if element in testlist else None)

或“ pythonic方式”,我不太喜欢它,因为代码不太清晰,但有时效率更高,

try:
    print testlist.index(element)
except ValueError:
    pass

5
除了在访问前进行测试外,您还可以尝试检查ValueError
kratenko 2013年

我认为他想发现所有情况,您似乎只给出了第一个。
tfv

@tfv我看不到如何得出这样的结论,因为问题是“项目”而不是“项目”。
mmj

40

使用枚举:

testlist = [1,2,3,5,3,1,2,1,6]
for position, item in enumerate(testlist):
    if item == 1:
        print position

10
for i in xrange(len(testlist)):
  if testlist[i] == 1:
    print i

xrange而不是要求的范围(请参阅注释)。


用xrange()替换range()-range()创建一个列表,xrange()创建一个迭代器。xrange()使用的内存更少,初始调用速度更快。
gnud

2
我同意python 2程序中的大型列表。请注意,尽管如此,“ range”仍将在python 3中运行(并像xrange IIRC一样运行)。“ xrange”正在像恐龙一样前进。
jakber

2
更新:xrange在Python 3.x中不再使用,因为新版本range已经过时了xrange
tim-oh

5

这是执行此操作的另一种方法:

try:
   id = testlist.index('1')
   print testlist[id]
except ValueError:
   print "Not Found"


2

请尝试以下方法:

testlist = [1,2,3,5,3,1,2,1,6]    
position=0
for i in testlist:
   if i == 1:
      print(position)
   position=position+1

1

如果列表足够大,并且只希望在稀疏索引中找到该值,则可以认为该代码可以更快执行,因为您不必迭代列表中的每个值。

lookingFor = 1
i = 0
index = 0
try:
  while i < len(testlist):
    index = testlist.index(lookingFor,i)
    i = index + 1
    print index
except ValueError: #testlist.index() cannot find lookingFor
  pass

如果您希望找到很多值,则应该将“索引”附加到列表中,并在最后打印列表以节省每次迭代的时间。


我做了一些计时测试。列表理解技术的运行速度比此代码快38%。(我将您的打印语句替换为outputlist.append调用)
Deestan's

我还进行了一些测试,其中列表大小为1至100之间的100000个随机值。在某些情况下,我编写的代码速度是后者的两倍。没有时间测试可以比作海报的应用程序了(当然,他们必须进行自我测试才能确定)。如果我的意见对这篇文章有害,我深表歉意。

0

我认为使用Tkinter库中的curselection()方法可能会很有用:

from Tkinter import * 
listbox.curselection()

此方法适用于Tkinter列表框小部件,因此您需要构造其中一个而不是列表。

这将返回如下位置:

(“ 0”,)(尽管Tkinter的更高版本可能会返回一个int列表)

这是第一个位置,编号将根据项目位置而变化。

有关更多信息,请参见以下页面:http : //effbot.org/tkinterbook/listbox.htm

问候。


1
有趣的主意。但是,由于这需要导入整个Tkinter库,所以这不是解决问题的最有效方法。
seaotternerd

3
这是一条低效而曲折的道路,即使解决了一些问题,我也会说这是错误的答案。

这个答案与问题无关。
2014年

0

为什么使事情复杂化?

testlist = [1,2,3,5,3,1,2,1,6]
for position, item in enumerate(testlist):
    if item == 1:
        print position

0

只是为了说明完整的示例,以及input_list其中具有searies1(example:input_list [0])的示例,您要在其中查找series2(example:input_list [1])并获取series2的索引(如果它在series1中存在)。

注意:certain condition如果条件简单,您将使用lambda表达式

input_list = [[1,2,3,4,5,6,7],[1,3,7]]
series1 = input_list[0]
series2 = input_list[1]
idx_list = list(map(lambda item: series1.index(item) if item in series1 else None, series2))
print(idx_list)

输出:

[0, 2, 6]

-2
testlist = [1,2,3,5,3,1,2,1,6]
for id, value in enumerate(testlist):
    if id == 1:
        print testlist[id]

我想这正是您想要的。;-)'id'将始终是列表中值的索引。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.