Encuentre el índice de un dict dentro de una lista, haciendo coincidir el valor del dict

Tengo una lista de dictados:

list = [{'id':'1234','name':'Jason'}, {'id':'2345','name':'Tom'}, {'id':'3456','name':'Art'}] 

¿Cómo puedo encontrar de manera eficiente la posición del índice [0], [1] o [2] haciendo coincidir on name = ‘Tom’?

Si esto fuera una lista unidimensional, podría hacer list.index () pero no estoy seguro de cómo proceder buscando los valores de los dictados dentro de la lista.

 tom_index = next((index for (index, d) in enumerate(lst) if d["name"] == "Tom"), None) # 1 

Si necesita obtener repetidamente el nombre, debe indexarlos por nombre (usando un diccionario), de esta manera las operaciones de obtención serían O (1). Una idea:

 def build_dict(seq, key): return dict((d[key], dict(d, index=index)) for (index, d) in enumerate(seq)) info_by_name = build_dict(lst, key="name") tom_info = info_by_name.get("Tom") # {'index': 1, 'id': '2345', 'name': 'Tom'} 

Una versión legible simple es

 def find(lst, key, value): for i, dic in enumerate(lst): if dic[key] == value: return i return -1 

No será eficiente, ya que debe recorrer la lista revisando todos los elementos que contiene (O (n)). Si quieres eficiencia, puedes usar dict de dictos . En cuanto a la pregunta, aquí hay una forma posible de encontrarla (aunque, si desea atenerse a esta estructura de datos, en realidad es más eficiente usar un generador, ya que Brent Newey ha escrito en los comentarios; consulte también la respuesta de tokland):

 >>> L = [{'id':'1234','name':'Jason'}, ... {'id':'2345','name':'Tom'}, ... {'id':'3456','name':'Art'}] >>> [i for i,_ in enumerate(L) if _['name'] == 'Tom'][0] 1 

Aquí hay una función que encuentra la posición del índice del diccionario si existe.

 dicts = [{'id':'1234','name':'Jason'}, {'id':'2345','name':'Tom'}, {'id':'3456','name':'Art'}] def find_index(dicts, key, value): class Null: pass for i, d in enumerate(dicts): if d.get(key, Null) == value: return i else: raise ValueError('no dict with the key and value combination found') print find_index(dicts, 'name', 'Tom') # 1 find_index(dicts, 'name', 'Ensnare') # ValueError: no dict with the key and value combination found 

Parece más lógico usar un combo de filtro / índice:

 names=[{}, {'name': 'Tom'},{'name': 'Tony'}] names.index(filter(lambda n: n.get('name') == 'Tom', names)[0]) 1 

Y si crees que podría haber múltiples partidos:

 [names.index(n) for item in filter(lambda n: n.get('name') == 'Tom', names)] [1] 

Para un iterable dado, more_itertools.locate produce posiciones de elementos que satisfacen un predicado.

 import more_itertools as mit iterable = [ {"id": "1234", "name": "Jason"}, {"id": "2345", "name": "Tom"}, {"id": "3456", "name": "Art"} ] list(mit.locate(iterable, pred=lambda d: d["name"] == "Tom")) # [1] 

more_itertools es una biblioteca de terceros que implementa recetas de itertools entre otras herramientas útiles.