简体   繁体   English

如何在Python列表中找到项目的位置?

[英]How can I find the locations of an item in a Python list of lists?

I want to find the location(s) of a specific item in a list of lists. 我想在列表列表中找到特定项目的位置。 It should return a list of tuples, where each tuple represents the indexes for a specific instance of the item. 它应该返回一个元组列表,其中每个元组代表该项的特定实例的索引。 For example: 例如:

list = [['1', '2', '4', '6'], ['7', '0', '1', '4']]
getPosition('1')  #returns [(0, 0), (1, 2)]
and getPosition('7') #returns [(1,0)]

If you want something that will both 如果你想要两种东西

  • find duplicates and 找到重复和
  • handle nested lists (lists of lists of lists of ...) 处理嵌套列表(列表列表...)

you can do something like the following: 你可以做以下的事情:

def get_positions(xs, item):
    if isinstance(xs, list):
        for i, it in enumerate(xs):
            for pos in get_positions(it, item):
                yield (i,) + pos
    elif xs == item:
        yield ()

Testing this: 测试这个:

>>> xs = [['1', '2', '4', '6'],
...       ['7', '0', '1', '4'],
...       [ [ '0', '1', '1'], ['1']]
...       ]
>>> print list(get_positions(xs, '1'))
[(0, 0), (1, 2), (2, 0, 1), (2, 0, 2), (2, 1, 0)]

It looks likes you want, for a list of sublists and a given item, to return a list of pairs where each pair is (the index of the sublist, the index of the item within the sublist). 对于子列表和给定项目的列表,您看起来想要返回每对对的列表列表(子列表的索引,子列表中项目的索引)。 You can do that using list comprehensions and Python's built in enumerate() function: 您可以使用列表推导和Python内置的enumerate()函数来实现:

def getPosition(list, item):
    return [(i, sublist.index(item)) for i, sublist in enumerate(list)]

Edit: See @scribble's answer above/below. 编辑:请参阅上面/下面的@ scribble的回答。

def getPosition(list, item):
    return [(i, sublist.index(item)) for i, sublist in enumerate(list) 
                                                      if item in sublist]
def get_positions(xs, target):
    return [(i,e.index(target)) for i,e in enumerate(xs)]

That's a good starting point. 这是一个很好的起点。 Presumably you have some sort of class such as 大概你有某种类,比如

class SomeClass:
    def __init__(self):
        self.xs = [['1','2','4','6'], ['7','0','1','4']]

    def get_positions(self, target):
        return [(i,e.index(target)) for i,e in enumerate(self.xs)]

which in this case would let you say 在这种情况下会让你说

model = SomeClass()
model.get_position(1)    # returns [(0,0), (1,2)]

Note that in both cases you'll get an exception if your target isn't in every one of your sublists. 请注意,在这两种情况下,如果您的目标不在每个子列表中,您将获得异常。 The question does not specify whether this is the desired behavior. 问题没有说明这是否是所需的行为。

If you don't want a exception if the item is not in the list try this. 如果您不希望例外,如果该项目不在列表中,请尝试此操作。 Also as a generator because they are cool and versatile. 也作为发电机,因为它们很酷且功能多样。

xs = [['1', '2', '4', '6'], ['7', '0', '1', '4']]
def get_positions(xs, item):
    for i, xt in enumerate( xs ):
        try: # trying beats checking
            yield (i, xt.index(item))
        except ValueError: 
            pass

print list(get_positions(xs, '1'))
print list(get_positions(xs, '6'))

# Edit for fun: The one-line version, without try:

get_positions2 = lambda xs,item: ((i,xt.index(item)) for  i, xt in enumerate(xs) if item in xt)

print list(get_positions2(xs, '1'))
print list(get_positions2(xs, '6'))

A while ago I wrote a library for python to do list matching that would fit the bill pretty well. 前段时间我为python写了一个库来做列表匹配,很适合这个账单。 It used the tokens ?, +, and * as wildcards, where ? 它使用令牌?,+和*作为通配符,在哪里? signifies a single atom, + is a non-greedy one-or-more, and * is greedy one-or-more. 表示单个原子,+是非贪婪的一个或多个,*是贪婪的一个或多个。 For example: 例如:

from matching import match

match(['?', 2, 3, '*'], [1, 2, 3, 4, 5])
=> [1, [4, 5]]

match([1, 2, 3], [1, 2, 4])
=> MatchError: broken at 4

match([1, [2, 3, '*']], [1, [2, 3, 4]])
=> [[4]]

match([1, [2, 3, '*']], [1, [2, 3, 4]], True)
=> [1, 2, 3, [4]]

Download it here: http://www.artfulcode.net/wp-content/uploads/2008/12/matching.zip 在此处下载: http//www.artfulcode.net/wp-content/uploads/2008/12/matching.zip

Here is a version without try..except, returning an iterator and that for 这是一个没有try..except的版本,返回一个迭代器和for

[['1', '1', '1', '1'], ['7', '0', '4']]

returns 回报

[(0, 0), (0, 1), (0, 2), (0, 3)] 


def getPosition1(l, val):
  for row_nb, r in enumerate(l):
      for col_nb in (x for x in xrange(len(r)) if r[x] == val):
         yield row_nb, col_nb

The most strainghtforward and probably the slowest way to do it would be: 最紧张,也可能是最慢的方法是:

    >>> value = '1'
    >>> l = [['1', '2', '3', '4'], ['3', '4', '5', '1']]
    >>> m = []
    >>> for i in range(len(l)):
    ...  for j in range(len(l[i])):
    ...   if l[i][j] == value:
    ...    m.append((i,j))
    ...
    >>> m
    [(0, 0), (1, 3)]

Here is another straight forward method that doesn't use generators. 这是另一种不使用生成器的直接方法。

def getPosition(lists,item):
    positions = []
    for i,li in enumerate(lists):
        j = -1
        try:
            while True:
                j = li.index(item,j+1)
                positions.append((i,j))
        except ValueError:
            pass
    return positions

l = [['1', '2', '4', '6'], ['7', '0', '1', '4']]
getPosition(l,'1')  #returns [(0, 0), (1, 2)]
getPosition(l,'9') # returns []

l = [['1', '1', '1', '1'], ['7', '0', '1', '4']]
getPosition(l,'1')  #returns [(0, 0), (0, 1), (0,2), (0,3), (1,2)]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM