【问题标题】:Finding the index of an item in a list of lists在列表列表中查找项目的索引
【发布时间】:2014-10-13 10:18:49
【问题描述】:

如果我有这个列表列表:

[[1,2,3,4],[5,6,7,8,9,10],[11,12,13]]

我怎样才能根据给定的值找到子列表本身的索引?

例如:

如果我的值为 2,则返回的索引为 0

如果我的值为 9,则返回的索引将为 1

如果我的值为 11,则索引为 2

【问题讨论】:

    标签: python list indexing integer


    【解决方案1】:

    只需使用enumerate:

    l = [[1,2,3,4],[5,6,7,8,9,10],[11,12,13]]
    
    # e.g.: find the index of the list containing 12
    # This returns the first match (i.e. using index 0), if you want all matches
    # simply remove the `[0]`
    print [i for i, lst in enumerate(l) if 12 in lst][0] 
    

    这个输出:

    [2]
    

    编辑:

    @hlt's 评论建议使用以下更有效的行为:

    next(i for i,v in enumerate(l) if 12 in v)
    

    【讨论】:

    • 这会找到所有的匹配项。您需要使用[0] 或(更有效)将事物转换为迭代器,然后使用next 提取第一个元素(即next(i for i,v in enumerate(l) if 12 in v)
    • @hlt:感谢您的评论。你说的很对!已更新。
    【解决方案2】:

    如果您想要所有索引,或者如果您只想要 first 出现,则使用 @jrd1 演示的 list-comp,然后:

    next((idx for idx, val in enumerate(your_list) if 2 in val), None)
    

    我们在这里使用None 作为默认值,而不是在任何子列表中都找不到该值的情况下引发StopIteration。如果您希望引发异常,请删除默认值。

    【讨论】:

      【解决方案3】:

      如果您有很多查询和/或动态列表,那么您最好制作一张地图。特别是一个 value:set 映射。您将值映射到包含该值的一组索引(子列表)。虽然如果列表没有改变,这效果最好。

      [[1,2,3,4],[5,6,7,8,9,10], [11,12,13], [1,2,3,4,5,6,7,8,9,10,11,12,13] 的示例:

      # Code for populating the map
      map = collections.defaultdict(set)
      index = 0
      for i,v in enumerate(l):
          for _ in v:
              map[index].add(i)
              index += 1
      
      # Result:
      map = {
          1: {0,3},
          2: {0,3},
          3: {0,3},
          4: {0,3},
          5: {1,3},
          6: {1,3},
          7: {1,3},
          8: {1,3},
          9: {1,3},
          10:{1,3},
          11:{2,3},
          12:{2,3},
          13:{2,3}
      }
      

      您还可以将子列表视为间隔(涵盖一系列索引)并允许 O(log N) 查找和 O(log N) 通过构建 interval tree 添加/删除子列表/元素。构建区间树需要 O(L log L),其中 L 是子列表的数量。

      【讨论】:

      • 这看起来不够优雅。这是有道理的,不要误会我的意思,但与next((idx for idx, val in enumerate(your_list) if 2 in val), None)相比,它看起来很糟糕。
      • 它只是看起来很丑,因为我只给出了我所想的结果。添加了 for 循环(我很想看到它作为单线完成)。还添加了关于使用区间树的注释。
      【解决方案4】:

      这是一个(虽然效率低,但简洁的)递归解决方案:

      def get_index(lst, num, index=0):
          if num in lst[index]:
              return index
          else:
              return get_index(lst, num, index + 1)
      

      【讨论】:

        猜你喜欢
        • 2023-02-11
        • 2016-01-25
        • 2010-09-15
        • 2013-01-07
        • 1970-01-01
        • 2018-07-31
        • 2020-07-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多