通过特定索引在列表中的列表中搜索

64 投票
14 回答
210698 浏览
提问于 2025-04-15 13:02

我有一个包含两个元素的列表的列表,我需要在里面查找东西。

如果这个列表是:

list = [['a','b'], ['a','c'], ['b','d']]

我可以通过下面的方式轻松查找一对:

['a','b'] in list

现在,有没有办法检查一下是否有一对,其中一个字符串只出现在第二个位置?我可以这样做:

for i in range (0, len(list)):
    if list[i][1]==search:
       found=1

但是有没有一种(更好的)方法,不用for循环?我不需要知道i的值,也不想在找到后继续循环。

14 个回答

16

在编程中,有时候我们会遇到一些问题,特别是在使用某些工具或库的时候。比如,有人可能在使用某个库时,发现它的某些功能不太好用,或者出现了错误。这种情况下,大家通常会去网上找解决办法,像是在StackOverflow这样的论坛上提问。

在这些论坛上,其他程序员会分享他们的经验和解决方案,帮助你解决问题。你可以看到很多人讨论同样的问题,提供不同的看法和建议。这就像是一个大家一起交流学习的地方,特别适合那些刚开始学习编程的人。

总之,遇到问题时,别忘了去这些社区寻求帮助,可能会找到意想不到的解决方案哦!

>>> the_list =[ ['a','b'], ['a','c'], ['b''d'] ]
>>> any('c' == x[1] for x in the_list)
True
85

这是用Python做这件事的一个比较好的方法:

data = [['a','b'], ['a','c'], ['b','d']]
search = 'c'
any(e[1] == search for e in data)

不过,我不会说这是“唯一正确的Python方式”,因为什么是Pythonic,什么不是,有时候是比较主观的,哪种方法比另一种更Pythonic也不一定好说。但用any()确实比用for循环更符合Python的风格,比如在RichieHindle的回答中提到的。

当然,any的实现内部也有一个循环,不过它一找到匹配的就会立刻退出这个循环。


因为我有点无聊,所以写了一个计时脚本来比较不同建议的性能,并根据需要修改了一些,使得它们的接口一致。我们要记住,最快的并不一定是最好的,速度快也不等于Pythonic。话虽如此,结果有点奇怪。显然,for循环的速度非常快,这让我有点意外,所以我对这些结果持保留态度,得先弄明白为什么会这样。

无论如何,当我使用问题中定义的列表,里面有三个子列表,每个子列表有两个元素时,从最快到最慢的结果是:

  1. RichieHindle的回答,使用for循环,耗时0.22微秒
  2. Terence Honles的第一个建议,创建一个列表,耗时0.36微秒
  3. Pierre-Luc Bedard的回答(最后的代码块),耗时0.43微秒
  4. Markus的回答和来自原问题for循环基本持平,耗时0.48微秒
  5. Coady的回答,使用operator.itemgetter(),耗时0.53微秒
  6. Alex Martelli的回答,使用ifilter()Anon的回答,都耗时0.67微秒(Alex的速度始终快大约半微秒)
  7. 还有jojo的回答、我的回答、Brandon E Taylor的回答(和我的完全相同)以及Terence Honles的第二个建议,使用any(),都在0.81-0.82微秒之间
  8. 最后是user27221的回答,使用嵌套列表推导,耗时0.95微秒

显然,实际的时间在其他人的硬件上并没有什么意义,但它们之间的差异可以让我们大致了解不同方法的接近程度。

当我使用一个更长的列表时,情况就有点变化了。我从问题中的列表开始,里面有三个子列表,然后又添加了197个子列表,总共200个子列表,每个长度为2。使用这个更长的列表,结果是:

  1. RichieHindle的回答,和短列表一样,耗时0.22微秒
  2. Coady的回答,使用operator.itemgetter(),同样是0.53微秒
  3. Terence Honles的第一个建议,创建一个列表,耗时0.36微秒
  4. 另一个几乎持平的结果是Alex Martelli的回答,使用ifilter()Anon的回答,耗时0.67微秒
  5. 再次接近持平的是我的回答、Brandon E Taylor的相同方法,以及Terence Honles的第二个建议,使用any(),都在0.81-0.82微秒之间

这些方法在扩展列表时保持了原来的时间。其他那些没有保持的结果是:

  1. 来自原问题for循环,耗时1.24微秒
  2. Terence Honles的第一个建议,创建一个列表,耗时7.49微秒
  3. Pierre-Luc Bedard的回答(最后的代码块),耗时8.12微秒
  4. Markus的回答,耗时10.27微秒
  5. jojo的回答,耗时19.87微秒
  6. 最后是user27221的回答,使用嵌套列表推导,耗时60.59微秒
51

你总是会有一个循环——可能有人会用很聪明的一行代码把循环藏在调用 map() 或类似的函数里,但循环始终是存在的。

我个人更喜欢干净简单的代码,除非性能是一个非常重要的因素。

这里有一个更符合Python风格的代码版本:

data = [['a','b'], ['a','c'], ['b','d']]
search = 'c'
for sublist in data:
    if sublist[1] == search:
        print "Found it!", sublist
        break
# Prints: Found it! ['a', 'c']

它会在找到匹配项后立刻跳出循环。

对了,你在 ['b''d'] 里有个拼写错误。

撰写回答