【问题标题】:Better way to search a list of lists for an item in python在python中搜索列表以查找项目的更好方法
【发布时间】:2013-04-22 20:49:34
【问题描述】:

有时我有一个列表列表,我需要在所有列表中搜索单个项目。我使用这个 python 代码:

boolean found = false

for(hayStack : listOfHayStacks){
   found = findNeedle(hayStack)

   if(found)
      break;
}

if(!found){
    // error case
}

我似乎经常遇到这种情况,我总觉得应该有更好的方法来处理它。

是否存在总结所有结果的:“atLeastOne”结构?

【问题讨论】:

  • 我经常遇到这种情况,我使用的方式与您完全相同。如果这里有更好的方法,我也很想知道。虽然您所说的“atLeastOne”构造是什么意思?
  • 在 Perl 中:warn "Didn't find a needle." unless any { findNeedle($_) } @listOfHayStacks; 如果您的偏好语言支持某种形式的 lambda 表达式,您可以创建一个类似的结构。但是底层算法是一样的;遍历每个元素,调用 findNeedle,找到一个就停止查找,如果没有找到则处理错误。
  • Calpis ::(来自 FogleBird 的回答)看起来 python 有一个“任何”结构,您可以将其与列表理解结合起来批量测试生成的布尔值。
  • 这不是算法问题,答案取决于编程语言或范例。函数式语言通常有一个 find 函数,它产生在任何类型的集合中找到的第一个项目。它们还提供根据是否找到值来调用两个不同的函数表达式(lambda 函数)。但是你提出了你的问题,这是大多数人都会给出的答案。
  • @JimBalter 我可能可以更好地提出这个问题,但我希望得到一些实际上与语言无关的东西(一种以不同方式重写问题的方法)。从下面的答案来看,Python 肯定支持函数式/lambda 表达式,但 Java 可能缺少它(至少在它获得 lambda 支持之前)

标签: java python for-loop foreach


【解决方案1】:

Python 对此有特殊的语法。

for haystack in haystacks:
    if find_needle(haystack):
        break
else:
    # error case (did not break)

根据您在代码中需要多少逻辑,您还可以执行以下操作:

some_needles_exist = any(find_needle(x) for x in haystacks)
all_stacks_have_needles = all(find_needle(x) for x in haystacks)

【讨论】:

  • 打败我。当发生短路问题时,我经常使用模式 any(val in stack for stack in stacks),而 find_needle(x) 只是测试集合中的成员资格。
  • 有谁知道“任何”和列表理解是否有办法停止第一个?如果 find_needle() 很昂贵,而我只想要第一个,那么如果不需要的话,最好不要遍历整个干草堆列表。
  • @Mark: any 短路。为什么你认为没有?
  • 啊!你说的对!我显然查看了错误的文档部分
【解决方案2】:

您始终可以创建一个单独的函数,在该函数中使用双 for 循环。它可能更具可读性:

for (hayStack : listOfHayStacks) {
    for (needle : hayStack) {
        if needle satisfies criteria
            return true
    }
}
return false

搜索所有干草堆的问题在于,如果您本可以在前几个干草堆中返回,那么您可能会浪费大量时间。

【讨论】:

    【解决方案3】:

    如果您要更多地专注于在大海捞针上找到或不找到针的操作,那么您可以做这样的事情:

    >>> criteria = lambda n: n == 3
    >>> def found(needle):
        if criteria(needle):
            print("Doing something as found")
            return True
        else: return False
    
    
    >>> def missed():
        print("Doing missed action")
        return False
    
    >>> wasfound = any(found(i) for i in range(2)) or missed()
    Doing missed action
    >>> wasfound
    False
    >>> wasfound = any(found(i) for i in range(4)) or missed()
    Doing something as found
    >>> wasfound
    True
    >>> 
    

    【讨论】:

      猜你喜欢
      • 2012-01-16
      • 2017-09-12
      • 1970-01-01
      • 2012-10-31
      • 2016-12-29
      • 1970-01-01
      • 1970-01-01
      • 2016-06-09
      • 1970-01-01
      相关资源
      最近更新 更多