how to search for an element in a list that is within another list?

5
  

I have the following list of lists.

[['julian', '0', '5'], ['ana', '10', '4']]
  

I need to use a function that tells me the position of any element within that list, I tried to use:

elemento = lista.index('julian')

print (elemento)
  

And I hope to return

>>>0,0

But it only works when I specify which of the lists within the main list to look for, how could I make it search all the lists and show the position?

    
asked by anonymous 05.06.2017 / 08:55

6 answers

5

For a more concise and pythonic solution, see this answer .

You can iterate through the entire list, element by element, by looking for the item you want - by finding, saving the index of the element in a variable and then returning it.

See an example:

lista = [['julian', '0', '5'], ['ana', '10', '4']]

# vamos criar uma função de 'busca'
def encontrar(elemento):
    pos_i = 0 # variável provisória de índice
    pos_j = 0 # idem

    for i in range (len(lista)): # procurar em todas as listas internas
        for j in range (i): # procurar em todos os elementos nessa lista
            if elemento in lista[i][j]: # se encontrarmos elemento ('ana')
                pos_i = i # guardamos o índice i
                pos_j = j # e o índice j
                break # saímos do loop interno
            break # e do externo
    return (pos_i, pos_j) # e retornamos os índices


r = encontrar('ana') # chamamos a função e salvamos em r
print(r) # imprime índices
print(lista[r[0]][r[1]]) # usa índices na lista como prova
  

Result:   

P.S.Thiscodewillnotworkifthereismorethanoneelementwiththesamevalue/name(itwillalwaysreturnthefirstoneitfinds)

Edit:

Tosearchformorethanoneitemwiththesamename,wecansavetheresulttoanewlist,likethis:

lista=[['julian','0','5'],['ana','10','4'],['10','ana','4']]defencontrar(elemento):lista_pos=[]#vamossalvarnestanovalistaforiinrange(len(lista)):forjinrange(i):ifelementoinlista[i][j]:lista_pos.append((i,j))#aquiadicionamoscadaíndicenalistareturnlista_pos#removemososbreaks,poisprecisamosprocurarnalistainteirar=encontrar('ana')print(r)#opróximoprintsófuncionabuscandopor'ana',poiseleesperaque#oretornosejapelomenosdoiselementosprint(lista[r[0][0]][r[0][1]],lista[r[1][0]][r[1][1]])
  

Result:  

    
05.06.2017 / 09:24
5

This code seems to be long, but it's just that because I tried to do something that you could understand:

lista = [['julian', '0', '5'], ['ana', '10', '4']]
print(lista)

procurar = input("Digite quem você procura: ")

for i in lista:
    local = lista.index(i) # Primeiro elemento
    for b in i:
        if b == procurar:
            local2 = lista[local].index(b) # Segundo elemento que está dentro do primeiro elemento, pouco confuso, mas é isso aí
            print("Quem você procura está na posição: lista[{}][{}]".format(local,local2))
            break

print("Quem você procura:",lista[local][local2])

Output:

>>> [['julian', '0', '5'], ['ana', '10', '4']]
>>> Digite quem você procura: 4
>>> Quem você procura está na posição: lista[1][2]
>>> Quem você procura: 4
    
05.06.2017 / 09:30
4

I did not analyze the other answers in depth, but I was a bit surprised at the amount of code for a simple task. So here's another solution:

def search (lista, valor):
    return [(lista.index(x), x.index(valor)) for x in lista if valor in x]

The use of this function, in this case, is:

lista = [['julian', '0', '4'], ['ana', '10', '4']]

def search (lista, valor):
    return [(lista.index(x), x.index(valor)) for x in lista if valor in x]

print(search(lista, "julian")) # [(0, 0)]
print(search(lista, "ana"))    # [(1, 0)]
print(search(lista, "0"))      # [(0, 1)]
print(search(lista, "4"))      # [(0, 2), (1, 2)]
print(search(lista, "foo"))    # []

Explaining the code a little:

x in lista if valor in x

will find the sub-list that is the desired value, storing this sub-list in x . The returned value will be (lista.index(x), x.index(valor)) , where the first will be the index of the sub-list in the list and the second value the index of the desired value within the sub-list. Note that the returned value will be a list with all occurrences of the value. For example, the value "4" is present twice in the list and therefore has two values returned.

See working at Ideone | Repl.it

The above solution fails when a sublist has the same value multiple times. For example, in the entry:

lista = [['julian', '0', '4', '4'], ['ana', '10', '4']]

The output for search(lista, '4') would be expected to be the (0, 2) , (0, 3) and (1, 2) pairs. because the first sub-list has twice the value '4' , but is, in fact, only (0, 2) and (1, 2) , because it stops searching when it finds the first element. To get around this, I've adapted the solution to fetch all the elements:

def get_all_indexes(lista, valor):
    return (i for i, v in enumerate(lista) if v == valor)

def search(lista, valor):
    return (list(product([indice], get_all_indexes(sublista, valor))) 
        for indice, sublista in enumerate(lista) if valor in sublista)

See working at Ideone | Repl.it

So the output of search(lista, '4') will be:

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

As expected.

Or even easier than that, a simple way:

lista = [['julian', '0', '4', '4'], ['ana', '10', '4']]

def search(lista, valor):
    for i, sublista in enumerate(lista):
        yield from ((i, j) for j, item in enumerate(sublista) if item == valor)

print( list(search(lista, '4')) )  # [(0, 2), (0, 3), (1, 2)]

See working at Ideone | Repl.it

    
06.06.2017 / 00:32
3

I've done a bit differently putting it inside a function, so it's something more generic.

lista = [ ["julian", "0", "5"], ["ana", "10", "4"] ]

# Realiza a busca dentro da lista
def busca(valor):
    i, j = 0,0 # indides incialmente definidos como 0

    # percorrendo lista externa
    for sub in lista:
        #verificando se o valor buscado esta dentro de alguma lista interna
        if valor in sub:
            # atribuindo o indice do valor buscado a j
            j = sub.index(valor)
            break # sai do loop
        i +=1 # incrementa
    else:
        # caso o valor buscado nao seja encontrado
        return None 

    return i,j


result = busca("julian")
print(result)

Using only a for you can scroll through the internal lists and then check using in if the search value is in any of them.

If the variable is j it will get the index of that value and the loop is stopped and then a tuple containing the values of i and j is returned.

If it does not find it, it will end the search in all lists and as break did not occur, it will fall into the else condition and then return None because the search value was not found.

    
05.06.2017 / 18:17
0

It has a slightly cleaner way you can do, basically it consists of searching all the objects that are part of the condition in the list, for this we use filter and lambda after this, with this list of objects that belong to the condition you can get the indexes through enumerate

Here is the code snippet responsible for this:

#Conjunto de dados
data = [['julian', '0', '5'], ['ana', '10', '4']]
finder = 'julian'

#Faz o filtro da lista atraves da condição especificada
condition = filter(lambda x: x[0] == finder, data)
#Converte o filtro para uma lista comum
filters = list(condition)

result = []
#Percorre cada item da lista enumerando
for index, item in enumerate(data):
    if item in filters:
        result.append(index)

Now within result you have all the indices that match the condition

    
05.06.2017 / 17:48
0

The previous answers, as I understand it, work well for the given example.

However, if we have an entry with a greater nesting, say [[[1, 2], [[[3]]]]] , no solution previously presented will give the element position.

For a generic solution, follow an example code that uses recursion to return a tuple that corresponds to the position of the element valor in lista , where each new element in the tuple corresponds to a higher level of nesting. p>

def busca(lista, valor):
    for el in lista:
        if valor == el:
            return (lista.index(el),)

        if isinstance(el, list):
            x = busca(el, valor)
            if x:
                return (lista.index(el),) + x

    return False

The busca function will return the first occurrence of the valor element in the lista list. It is possible that valor is another list.

Sample results:

lista = [[1, 2], [[[3]]]] | valor = 3
posição = (1, 0, 0, 0)

lista = [[1, 2], [[[3]]]] | valor = 1
posição = (0, 0)

lista = [1, 2, [1, 2]] | valor = 2
posição = (0,)

lista = [1, 2, [1, 2]] | valor = [1, 2]
posição = (2,)
    
06.06.2017 / 02:52