Tengo una lista de diccionarios que quiero filtrar.
[{"Slope": -0.562, "Count": 3},
{"Slope": -0.362, "Count": 6},
{"Slope": -0.762, "Count": 8},
{"Slope": -0.562, "Count": 12},
{"Slope": 2.5, "Count": 34},
{"Slope": 1.52, "Count": 2},
{"Slope": .56, "Count": 6}]
Mi objetivo es obtener una lista de dos diccionarios. Uno con el "conteo más alto y una pendiente POSITVE" y el otro con el "conteo más alto y la pendiente NEGATIVA".
Mi plan era filtrar todos los positivos y negativos, luego ordenar cada lista y luego crear una nueva lista con el primer registro de cada una.
Ordenar la lista no es un problema para mí, ¡tengo esto!
lines_lst.sort(key=lambda i: i['lines_count'])
Pero el filtrado no parece funcionar cuando intento esto, ya que devuelve un diccionario.
positive_lines = next(item for item in lines_lst if item["Slope"] > 0)
¿Alguien tiene una solución que termine con lo siguiente?
[{"Slope": -0.562, "Count": 12},{"Slope": 2.5, "Count": 34}]
6 respuestas
Desea max y min ... úselos y aplique una función de tecla adecuada; de hecho, con las tuplas solo necesita max:
data = [{"Slope": -0.562, "Count": 3},
{"Slope": -0.362, "Count": 6},
{"Slope": -0.762, "Count": 8},
{"Slope": -0.562, "Count": 12},
{"Slope": 2.5, "Count": 34},
{"Slope": 1.52, "Count": 2},
{"Slope": .56, "Count": 6}]
m1 = max(data, key= lambda x: (x["Slope"]>0, x["Count"]))
m2 = max(data, key= lambda x: (x["Slope"]<0, x["Count"]))
result = [m1,m2]
print(result)
Salida:
[{'Slope': 2.5, 'Count': 34}, {'Slope': -0.562, 'Count': 12}]
Las tuplas se ordenan por el primer valor, luego por el segundo valor: puede construir tuplas y usarlas como función de tecla máxima.
Para abordar su información adicional en la respuesta de Patrick, puede hacer esto para ordenar primero las listas negativas / positivas:
positives = sorted((v for v in data if v['Slope'] >= 0), key=lambda x: x['Count'])
negatives = sorted((v for v in data if v['Slope'] < 0), key=lambda x: x['Count'])
# positives:
# [{'Slope': 1.52, 'Count': 2}, {'Slope': 0.56, 'Count': 6}, {'Slope': 2.5, 'Count': 34}]
# negatives:
# [{'Slope': -0.562, 'Count': 3}, {'Slope': -0.362, 'Count': 6}, {'Slope': -0.762, 'Count': 8}, {'Slope': -0.562, 'Count': 12}]
Obtener el máximo en este punto es simple. Solo recupera el último elemento:
max_pox = positives[-1] # {'Slope': 2.5, 'Count': 34}
max_neg = negatives[-1] # {'Slope': -0.562, 'Count': 12}
O si lo prefiere en forma de lista:
[x[-1] for x in (negatives, positives)]
# [{'Slope': -0.562, 'Count': 12}, {'Slope': 2.5, 'Count': 34}]
Puede pasar una expresión del generador a max()
:
>>> max((d for d in lines_lst if d["Slope"] > 0), key=lambda d: d["Count"])
{'Slope': 2.5, 'Count': 34}
>>> max((d for d in lines_lst if d["Slope"] < 0), key=lambda d: d["Count"])
{'Slope': -0.562, 'Count': 12}
Por supuesto, esta solución itera a través de lines_lst
dos veces. Si tiene una entrada realmente grande, puede recorrerla una vez, con avidez, haciendo un seguimiento del máximo / mínimo en ejecución:
import sys
max_pos, max_neg = {"Count": -sys.maxsize}, {"Count": -sys.maxsize}
for d in lines_lst:
ct = d["Count"]
if d["Slope"] > 0 and ct > max_pos["Count"]:
max_pos = d
elif d["Slope"] < 0 and ct > max_neg["Count"]:
max_neg = d
Pero en Python-land, esto probablemente solo sea valioso si su entrada es realmente grande y difícil de manejar.
Tenga en cuenta que en ambos casos, _más modificaciones a max_pos
/ max_neg
constituyen modificaciones a los miembros de lines_lst
, porque esos miembros son diccionarios mutables.
¿Esto funciona?
data = [{"Slope": -0.562, "Count": 3},
{"Slope": -0.362, "Count": 6},
{"Slope": -0.762, "Count": 8},
{"Slope": -0.562, "Count": 12},
{"Slope": 2.5, "Count": 34},
{"Slope": 1.52, "Count": 2},
{"Slope": .56, "Count": 6}]
positive_lines = []
negative_lines = []
for i in range(len(data)):
if data[i]["Slope"] < 0:
negative_lines.append(data[i])
else:
positive_lines.append(data[i])
max_counts = []
max_counts.append(max(positive_lines, key=lambda x:x['Count']))
max_counts.append(max(negative_lines, key=lambda x:x['Count']))
print(max_counts)
Salida:
[{'Slope': 2.5, 'Count': 34}, {'Slope': -0.562, 'Count': 12}]
Puede hacerlo de la siguiente manera:
inList = [{"Slope": -0.562, "Count": 3},
{"Slope": -0.362, "Count": 6},
{"Slope": -0.762, "Count": 8},
{"Slope": -0.562, "Count": 12},
{"Slope": 2.5, "Count": 34},
{"Slope": 1.52, "Count": 2},
{"Slope": .56, "Count": 6}]
maximum = max(filter(lambda elem: elem['Slope'] > 0, inList), key=lambda e: e['Count'])
minimum = max(filter(lambda elem: elem['Slope'] < 0, inList), key=lambda e: e['Count'])
Esto devolverá:
{'Slope': 2.5, 'Count': 34}
{'Slope': -0.562, 'Count': 12}
Cree una clave Count2 que sea negativa para pendientes negativas. Luego ordena por Count2 y toma el primer y último elemento.
lines_lst = [{"Slope": -0.562, "Count": 3},
{"Slope": -0.362, "Count": 6},
{"Slope": -0.762, "Count": 8},
{"Slope": -0.562, "Count": 12},
{"Slope": 2.5, "Count": 34},
{"Slope": 1.52, "Count": 2},
{"Slope": .56, "Count": 6}]
for i in range(len(lines_lst)):
lines_lst[i]['Count2'] = lines_lst[i]['Count']*lines_list[i]['Slope']/abs(lines_list[i]['Slope'])
lines_lst.sort(key=lambda i: i['Count2'])
[lines_lst[0], lines_lst[-1]]
Preguntas relacionadas
Nuevas preguntas
python
Python es un lenguaje de programación multipropósito, de tipificación dinámica y de múltiples paradigmas. Está diseñado para ser rápido de aprender, comprender y usar, y hacer cumplir una sintaxis limpia y uniforme. Tenga en cuenta que Python 2 está oficialmente fuera de soporte a partir del 01-01-2020. Aún así, para preguntas de Python específicas de la versión, agregue la etiqueta [python-2.7] o [python-3.x]. Cuando utilice una variante de Python (por ejemplo, Jython, PyPy) o una biblioteca (por ejemplo, Pandas y NumPy), inclúyala en las etiquetas.