Python 按给定索引在列表列表中搜索
我有两个项目列表,需要搜索其中的内容 如果列表为:Python 按给定索引在列表列表中搜索,python,list,Python,List,我有两个项目列表,需要搜索其中的内容 如果列表为: 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,也
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
,也不需要在找到循环后继续循环。你总是会有一个循环-有人可能会提出一个聪明的单行程序,在调用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']
中有一个打字错误)
编辑以添加:
David在中使用的any和我在中使用的都将在找到匹配项时结束,因为我们使用的是生成器表达式。下面是一个使用无限生成器的测试,以表明:
def mygen():
''' Infinite generator '''
while True:
yield 'xxx' # Just to include a non-match in the generator
yield 'd'
print 'd' in (x for x in mygen()) # True
print any('d' == x for x in mygen()) # True
# print 'q' in (x for x in mygen()) # Never ends if uncommented
# print any('q' == x for x in mygen()) # Never ends if uncommented
我只是喜欢在中简单地使用,而不是同时使用=和任何以下是Pythonic方法:
data = [['a','b'], ['a','c'], ['b','d']]
search = 'c'
any(e[1] == search for e in data)
或者。。。我不会说这是“一种真正的肾盂疗法”,因为在某种程度上,什么是肾盂疗法,什么不是,或者哪种方法比另一种方法更具肾盂疗法,都会变得有点主观。但是使用any()
显然比for
循环更典型的Python风格,例如
当然,在any
的实现中有一个隐藏的循环,尽管它在找到匹配项后立即中断循环
因为我很无聊,所以我制作了一个计时脚本来比较不同建议的性能,根据需要修改其中一些,使API保持一致。现在,我们应该记住,最快并不总是最好的,而且快速和蟒蛇绝对不是一回事。尽管如此,结果是。。。奇怪。显然,for循环速度非常快,这不是我所期望的,因此我对它们持怀疑态度,不理解它们为什么会出现这种情况 不管怎样,当我使用问题中定义的列表和三个子列表,每个子列表由两个元素组成时,从最快到最慢,我得到以下结果:
for
循环,时钟频率为0.22μs操作符.itemgetter()
,速度为0.53μsifilter()
和在0.67μs时(Alex的速度始终快半微秒)之间的平衡any()
,都以0.81-0.82μs的速度进入操作符.itemgetter()
ifilter()
和在0.67μs时的另一个虚拟连接any()
,两者之间的联系非常紧密,都是0.81-0.82μs
zip()。星号将列表的内容作为参数发送到zip
,因此您可以有效地分别传递这三个列表,这正是zip
想要的。剩下的就是检查由您感兴趣的索引元素组成的列表中是否有“b”
(或任何东西)。Markus有一种方法可以避免在中使用这个词,这是另一种方法,在列表中应该有更好的性能
import itertools
found = any(itertools.ifilter(lambda x:x[1]=='b', the_list)
使用gen exp没有错,但是如果目标是内联循环
>>> import itertools, operator
>>> 'b' in itertools.imap(operator.itemgetter(1), the_list)
True
也应该是最快的。以上各项看起来都不错
但是你想保留结果吗
如果是的话
您可以使用以下命令
result = [element for element in data if element[1] == search]
然后是一个简单的
len(result)
让您知道是否找到了任何东西(现在您可以对结果进行处理)
当然这不处理长度小于1的元素
(除非您知道它们总是大于
长度1,在这种情况下,您应该使用元组吗?(元组是不可变的)
如果您知道所有项目都是设定长度,您还可以执行以下操作:
any(second == search for _, second in data)
或对于len(数据[0])==4:
…我建议使用
for element in data:
...
而不是
for i in range(len(data)):
...
(供将来使用,除非您想保存或使用“i”,并且您知道
“0”不是必需的,只有在启动时才需要使用完整语法
在非零值时)那么:
list =[ ['a','b'], ['a','c'], ['b','d'] ]
search = 'b'
filter(lambda x:x[1]==search,list)
这将返回列表列表中的每个列表,第二个元素等于search 下面给出的是一个
any(second == search for _, second, _, _ in data)
for element in data:
...
for i in range(len(data)):
...
list =[ ['a','b'], ['a','c'], ['b','d'] ]
search = 'b'
filter(lambda x:x[1]==search,list)
for i in range (0,len(a)):
sublist=a[i]
for i in range(0,len(sublist)):
if search==sublist[i]:
print "found in sublist "+ "a"+str(i)
list =[ ['a','b'], ['a','c'], ['b','d'] ]
Search = 'c'
# return if it find in either item 0 or item 1
print [x for x,y in list if x == Search or y == Search]
# return if it find in item 1
print [x for x,y in list if y == Search]
list =[ ['a','b'], ['a','c'], ['b','d'] ]
search = 'c'
any([ (list.index(x),x.index(y)) for x in list for y in x if y == search ] )
def deapFind( theList, key, value ):
result = False
for x in theList:
if( value == x[key] ):
return True
return result
theList = [{ "n": "aaa", "d": "bbb" }, { "n": "ccc", "d": "ddd" }]
print 'Result: ' + str (deapFind( theList, 'n', 'aaa'))