Python. Получить минимальное и максимальное значение из файла
Требуется получить максимальное и минимальное значение из второго столбца и вывести соответствующую запись из 1 столбца. Пример файла:
14:00:30|174
14:05:30|173
14:10:30|173
14:15:30|172
14:20:30|172
14:25:30|171
т.е пример: min: 171 (14:25:30) max: 174 (14:00:30)
Минимальное и максимальное значение получаю так:
import csv
with open('base.txt', "r") as csvfile:
data = csv.reader(csvfile, delimiter = '|')
minval = []
maxval = []
for i in data:
minval.append(i[1])
maxval.append(i[1])
print(min(minval))
print(max(maxval))
Как добавить вывод значения из 1 столбца, который соответствует минимальному и максимальному значению из 2 столбца?
Ответы (4 шт):
with open('your.txt') as f:
lines = [i for i in f]
print(max(int(i.split('|')[1]) for i in lines if i != '\n'))
print(min(int(i.split('|')[1]) for i in lines if i != '\n'))
with open('base.txt', 'r') as csvfile:
data = csv.reader(csvfile, delimiter = '|')
print(min(data, key = lambda x: x[1])
print(max(data, key = lambda x: x[1])
Либо:
with open('base.txt', 'r') as csvfile:
data = csv.reader(csvfile, delimiter = '|')
data = list(data)
minimal = min(data, key = lambda x: x[1])
maximum = max(data, key = lambda x: x[1])
min_index = []
max_index = []
for i in range(len(data)):
if data[i] == minimal:
min_index.append(i)
if data[i] == maximum:
max_index.append(i)
for i in min_index:
print(data[i])
for i in max_index:
print(data[i])
from itertools import tee
from operator import itemgetter
import csv
with open('base.txt', 'r') as csvfile:
reader = csv.reader(csvfile, delimiter='|')
payload_it = filter(len, reader) # Выкидываем пустые строки (csv их вообще не должен содержать)
min_it, max_it = tee(payload_it, 2) # Разделяем один поток на 2 независимых
key = itemgetter(1) # Ключ для выбора минимума, максимума (то же самое, что и item[1])
print(min(min_it, key=key), max(max_it, key=key))
Файл прочитается всего 1 раз, получите минимум и максимум (лексикографический) по второму столбцу.
Но это тоже плохой вариант, потому что в памяти будет храниться 2 копии содержимого файла (минимум и максимум ищутся в этих копиях). Поэтому лучше завести какие-то minimum, maximum значения и просто обновлять их при одном итерировании по файлу. Решение лучше я описал, но реализовывать его мне лень :)
Вариант с одним проходом и нахождением минимума максимума за проход без хранения всего содержимого файла в памяти на каком-либе из этапов:
from operator import itemgetter
import csv
def min_max(*args, key=lambda x: x):
"""
Возвращает наименьший и наибольший элементы в итерируемом объекте
или наименьший и наибольший из двух или более аргументов.
:param args: Множество аргументов или один итерируемый
:param key: Ключ, по которому будет выполняться сравнение
:return: Наименьший и наибольший элементы
"""
if len(args) == 1:
iterable = args[0]
else:
iterable = args
it = iter(iterable)
try:
min = max = next(it)
min_key, max_key = map(key, (min, max))
except StopIteration:
raise ValueError('Empty sequence')
for item in it:
keyed = key(item)
if keyed < min_key:
min = item
min_key = keyed
if keyed > max_key:
max = item
max_key = keyed
return min, max
if __name__ == '__main__':
with open('base.txt', 'r') as csvfile:
reader = csv.reader(csvfile, delimiter='|')
payload_it = filter(len, reader) # Выкидываем пустые строки (csv их вообще не должен содержать)
print(min_max(payload_it, key=itemgetter(1)))
Вам не нужно создать 2 списки
minvalиmaxval, хватит один.
Значит 1-ое улучшение вашей программы :import csv with open('base.txt', "r") as csvfile: data = csv.reader(csvfile, delimiter = '|') val = [] for i in data: val.append(i[1]) print(min(val)) print(max(val))Вы можете использовать тот факт, что кортежи сравниваются так, что в первую очередь сравниваются первые элементы кортежей (и только если они равны, сравниваются и вторые, и т.д.).
Значит, в список
valдобавляйте не только значения из второго столбца, но пару(второй_столбец, первый_столбец):import csv with open('base.txt', "r") as csvfile: data = csv.reader(csvfile, delimiter = '|') val = [] for i in data: val.append((i[1], i[0])) # здесь разница print(min(val)) print(max(val))Когда вам не нравится формат вывода, вместо последних команд
print(min(val)) print(max(val))используйте например
print(f"min: {min(val)[0]} ({min(val)[1]}), max: {max(val)[0]} ({max(val)[1]})")min: 171 (14:25:30), max: 174 (14:00:30)или то же самое более наглядно
minval, maxval = min(val), max(val) // minval = min(val); maxval = max(val) min_num, min_time = minval // min_num = minval[0]; min_time = minval[1] max_num, max_time = maxval print(f"min: {min_num} ({min_time}), max: {max_num} ({max_time})")