subarray slicing index array python arrays indexing tuples

slicing - Buscar índice de elemento anidado en python



slice python 3 (3)

He estado trabajando con algunas matrices relativamente complejas, como:

array = [ "1", 2, ["4", "5", ("a", "b")], ("c", "d")]

y estaba buscando una manera de encontrar un elemento y recuperar es "índice" (¿Está bien referirse a la ubicación del elemento como "a" - que está dentro de una Tupla como índice en el mismo nivel que la matriz?)

Ahora mi primer pensamiento fue utilizar algo así como una función auxiliar simple como:

def myindex(nestedlist, item): for i in nestedlist: if item in i: index = [] index.append(i) index.append(i.index(item)) return index

Pero estoy seguro de que puede adivinar que dicha función no servirá de mucho, sobre todo porque no sé de antemano cuántos niveles podría tener la matriz, y qué podría contener cada nivel (en términos de tipo de datos / estructura )

Cualquier sugerencia en la dirección correcta sería muy apreciada.


Llego un poco tarde a la fiesta, pero pasé varios minutos en ella, así que siento que debería publicarse de todos modos :)

def getindex(container, target, chain=None): if chain is None: chain = list() for idx, item in enumerate(container): if item == target: return chain + [idx] if isinstance(item, collections.Iterable) and not isinstance(item, str): # this should be ... not isinstance(item, basestring) in python2.x result = getindex(item, target, chain + [idx]) if result: return result return None


Lo que quieres es algo así como:

def myindex(lst, target): for index, item in enumerate(lst): if item == target: return [index] if isinstance(item, (list, tuple)): path = myindex(item, target) if path: return [index] + path return []

Recursivo, esto tratará con profundidad de anidamiento arbitraria (hasta el límite de recursión).

Para su array ejemplo, obtengo:

>>> myindex(array, "a") [2, 2, 0]

Como alude Adán en los comentarios, la comprobación explícita de los tipos de instancia no es muy pitonica. Una alternativa tipo pato , "más fácil de pedir perdón que permiso" sería:

def myindex(lst, target): for index, item in enumerate(lst): if item == target: return [index] if isinstance(item, str): # or ''basestring'' in 2.x return [] try: path = myindex(item, target) except TypeError: pass else: if path: return [index] + path return []

El manejo específico de cadenas es necesario ya que incluso una cadena vacía se puede iterar, lo que causa recursiones sin fin.


array = ["1", 2, ["4", "5", ("a", "b")], ("c", "d")]

def find_index(array, item, index=None): if not index: index = [] try: i = array.index(item) except: for new_array in array: if hasattr(new_array, ''__iter__''): i = find_index(new_array, item, index+[array.index(new_array)]) if i: return i else: return index + [i] return None

Esto da:

>>> find_index(array, 1) >>> find_index(array, "1") [0] >>> find_index(array, 2) [1] >>> find_index(array, "4") [2, 0]