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
  • 这将创建一个0.36μs的列表
  • ,在0.43μs
  • 在0.48μs时,基本上与回路的相连
  • 使用
    操作符.itemgetter()
    ,速度为0.53μs
  • 足够接近,可以算作使用
    ifilter()
    和在0.67μs时(Alex的速度始终快半微秒)之间的平衡
  • 另一个足够紧密的连接,mine(与mine相同)和使用
    any()
    ,都以0.81-0.82μs的速度进入
  • 然后使用嵌套列表理解,0.95μs
  • 显然,实际的计时在其他任何硬件上都没有意义,但是它们之间的差异应该让我们知道不同的方法有多接近

    当我使用较长的列表时,情况会有一点变化。我从问题中的列表开始,有三个子列表,并附加了另外197个子列表,总共200个子列表,每个子列表长度为2。使用这个较长的列表,以下是结果:

  • ,与较短列表相同,为0.22μs
  • 再次以0.53μs的速度使用
    操作符.itemgetter()
  • 这将创建一个0.36μs的列表
  • 使用
    ifilter()
    和在0.67μs时的另一个虚拟连接
  • 同样,我的答案、相同的方法和使用
    any()
    ,两者之间的联系非常紧密,都是0.81-0.82μs
  • 当列表扩展时,这些是保持其原始时间的。其余的都不是

  • 在1.24μs时,回路的
  • 它创建了一个列表,为7.49μs
  • ,在8.12μs
  • ,在10.27μs
  • ,在19.87μs
  • 最后使用嵌套列表理解,60.59μ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'))