我有一个包含两个项目的列表,需要在其中搜索内容。
如果列表是:
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,也不需要在找到它之后继续循环。
发布于 2009-07-20 21:39:56
你总会有一个循环--有人可能会想出一个聪明的一行程序,将循环隐藏在对map()或类似程序的调用中,但它总是会存在的。
除非性能是一个主要因素,否则我更喜欢拥有干净和简单的代码。
下面是您的代码的一个更具Pythonic风格的版本:
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']中有一个拼写错误。)
发布于 2009-07-20 21:47:28
下面是Pythonic式的方法:
data = [['a','b'], ['a','c'], ['b','d']]
search = 'c'
any(e[1] == search for e in data)或者..。我不会说这是“一种真正的Pythonic方式”,因为在某种程度上,什么是Pythonic,什么不是,或者哪种方法比另一种方法更Pythonic,会变得有点主观。但是使用any()肯定比在例如RichieHindle's answer中的for循环更典型的Python风格,
当然,在any的实现中有一个隐藏的循环,尽管一旦找到匹配,它就会中断循环。
因为我很无聊,所以我做了一个计时脚本来比较不同建议的性能,根据需要修改其中的一些建议,以使API相同。现在,我们应该记住,最快并不总是最好的,而且快速绝对不是Pythonic式的东西。话虽如此,结果是...真奇怪。显然,for循环的速度非常快,这不是我所期望的,所以我对它们持保留态度,并不理解它们为什么会这样。
无论如何,当我使用问题中定义的三个子列表,每个子列表包含两个元素时,从最快到最慢,我得到了以下结果:
operator.itemgetter()时,在Markus's answer和来自the original question的for循环之间,在0.53 for的ifilter()和<μ>c29之间的关系,在0.67s时(Alex的大约是0.5微秒,在jojo's answer、faster)any()的Terence Honles' second suggestion之间的关系足够紧密,所有这些都是在0.81-0.82s上使用嵌套列表理解的
显然,实际的计时在其他任何人的硬件上都没有意义,但它们之间的差异应该可以让我们对不同方法的接近程度有所了解。
当我使用一个较长的列表时,情况会发生一些变化。我从问题中的列表开始,有三个子列表,并附加了另外197个子列表,总共有200个子列表,每个子列表的长度为2。使用这个较长的列表,结果如下:
ifilter()和Anon's answer之间的另一个虚拟关系,在0.67Code这些是在列表扩展时保持其原始计时的那些。其余的,不是,是
在1.24μs
for循环从the original question创建一个列表,在7.49μs发布于 2009-07-20 21:47:42
>>> the_list =[ ['a','b'], ['a','c'], ['b''d'] ]
>>> any('c' == x[1] for x in the_list)
Truehttps://stackoverflow.com/questions/1156087
复制相似问题