Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Скриптовые языки программирования > Python
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 13.01.2020, 13:27   #1
archerix
Форумчанин
 
Регистрация: 13.09.2019
Сообщений: 119
По умолчанию Считывание чисел из файла в списки

Здравствуйте, народ

Взялся тут изучить основы Питона, и вот такой вот новичковский вопрос возник о записи и считывании данных из файла. Типовым случаем предполагается наличие файла на две колонки чисел. Порывшись в интернетах, составил из надерганных оттуда кусочков такую вот программку.
Код:
n=5
arrx=[0]*n
arry=[0]*n

for i in range(0,n):
    arrx[i]=i
    arry[i]=i*i
    
for i in range(0,n): print("x = ", arrx[i], "y = ", arry[i])

f = open('test.txt', 'w')
for i in range(0,n): f.write(str(arrx[i]) + ' ' + str(arry[i]) + '\n')
f.close()

print('')

with open('test.txt') as file:
    lst = list()
    for line in file.readlines(): 
        lst.extend(line.rstrip().split(' ')) 

print(lst)

for i in range(0,n) :
    arrx[i]=lst[2*i]
    arry[i]=lst[2*i+1]
    
print('')

for i in range(0,n): print("x = ", arrx[i], "y = ", arry[i])
Как-то довольно замысловато все получилось, особенно считывание через дополнительный список. А можно ли то же самое сделать короче и красивше?
archerix вне форума Ответить с цитированием
Старый 13.01.2020, 16:26   #2
Arkuz
Форумчанин
 
Аватар для Arkuz
 
Регистрация: 22.09.2007
Сообщений: 540
По умолчанию

С именоваными параметрами удобнее работать через словарь, а не через списки. В итоге получим список словарей [{'x': 1, 'y': 1}, ...]. Так же этот словарь мы используем как буфер, когда надо наполняем, когда надо чистим, затем вновь наполняем. Ну и повторяющиеся операции выносим в функции. Работу со строками я выполнил через f-строки, можно использовать форматирование строки через метод ''.format(), это удобнее и читабельнее чем просто использовать конкатенацию строк через + и приведение типа str().

Кода меньше не стало, но, мне кажется, теперь этот код понятнее и удобнее для поддержания.

Код:
n = 5
coord_list = [] # список словарей с координатами [{'x': 1, 'y': 1}, ...]

# заполнение списка начальными координатами
def fill_coord_list():
    for i in range(0, n):
        coord_list.append({
            'x': i,
            'y': i * i,
        })

# печать списка координат
def print_coord_list():
    for i in coord_list:
        print(f"x = {i['x']}, y = {i['y']}")
    print('')

# сохранить список в файл
def save_coord_list_to_file(filename):
    with open(filename, 'w') as file:
        for i in coord_list:
            file.write(f"{i['x']} {i['y']}\n")

# заполнить список координат из файла
def open_coord_list_from_file(filename):
    coord_list = []
    with open(filename) as file:
        for line in file.readlines():
            split_val = line.rstrip().split(' ')
            coord_list.append({
                'x': split_val[0],
                'y': split_val[1],
            })

filename = 'test.txt'
fill_coord_list()
print_coord_list()
save_coord_list_to_file(filename)
open_coord_list_from_file(filename)
print_coord_list()
Вот так можно менять значения в словаре:

Код:
#в цикле
for i in coord_list:
    i['x'] = i['x'] + 10
    i['y'] = i['y'] + 100

#конкретную координату в списке
coord_list[0]['x'] = 200
coord_list[2]['y'] = 300

Последний раз редактировалось Arkuz; 13.01.2020 в 16:37.
Arkuz вне форума Ответить с цитированием
Старый 13.01.2020, 19:50   #3
archerix
Форумчанин
 
Регистрация: 13.09.2019
Сообщений: 119
По умолчанию

Спасибо, будем изучать

Но все же - можно ли как-то сразу считать в два списка?

Последний раз редактировалось archerix; 14.01.2020 в 10:02.
archerix вне форума Ответить с цитированием
Старый 14.01.2020, 12:14   #4
archerix
Форумчанин
 
Регистрация: 13.09.2019
Сообщений: 119
По умолчанию

Ага, так можно записать, с f-строками как-то красивше.
Код:
f = open('test.txt', 'w')
for i in range(0,n): f.write(f"{arrx[i]} {arry[i]}\n")
f.close()
Логика подсказывает, что точно так же должно быть можно и считать сразу в два списка, но что-то не хочет
Код:
f.read(f"{arrx[i]} {arry[i]}\n")
Не работает И примеров считывания чего-то таким способом что-то не могу нарыть в сети.

Последний раз редактировалось archerix; 14.01.2020 в 12:23.
archerix вне форума Ответить с цитированием
Старый 14.01.2020, 12:52   #5
archerix
Форумчанин
 
Регистрация: 13.09.2019
Сообщений: 119
По умолчанию

Вот так вроде считалось за раз.

Код:
f = open('test.txt', 'r')
for line in f:
	words = line.split()       
	arrx.append(int(words[0]))
	arry.append(int(words[1]))
Но все равно мне кажется, что как-то можно считать и еще короче

Последний раз редактировалось archerix; 14.01.2020 в 13:00.
archerix вне форума Ответить с цитированием
Старый 14.01.2020, 18:10   #6
Arkuz
Форумчанин
 
Аватар для Arkuz
 
Регистрация: 22.09.2007
Сообщений: 540
По умолчанию

А как по другому?
Если есть 2 массива и строка из файла.
Строку надо считать, распарсить и положить в каждый из массивов.

Если работа с файлами используется только в учебных целях, то все эти потуги понятны. ))

А вообще можно сразу сохранять и читать в json, xml, csv и для этого есть готовые библиотеки.
Так же можно самому реализовать механизмы сохранения и загрузки из файла данных как object.

Фишка в том, что не надо будет циклами проходить и сохранять все значения. Вы будете в одну команду сохранять файл и в одну команду загружать его. И работать потом уже ни как с массивами, а как с объектом.

И списки это не очень хорошая идея. Сейчас у вас 2 параметра x и y. А если их будет 20? Делать 20 списков? )))

Поэтому я предложил альтернативный вариант на словарях.

Цитата:
Вот так вроде считалось за раз.
Код:
f = open('test.txt', 'r')
for line in f:
	words = line.split()       
	arrx.append(int(words[0]))
	arry.append(int(words[1]))
Да как бы не за раз... Считали файл в буфер и в буфере построчно считываете значения в цикле for line in f:


Цитата:
Логика подсказывает, что точно так же должно быть можно и считать сразу в два списка, но что-то не хочет
Код:
f.read(f"{arrx[i]} {arry[i]}\n")
Логика подсказывает неверно )) Когда вы пишете в файл в функцию write передаете строку, которую пишете. А у функции чтения такого механизма нет. Вы просто считываете строку из файла, а уже потом делаете с ней, что хотите.
В функцию write надо передать строку, а функция read возвращает строку.

Последний раз редактировалось Arkuz; 14.01.2020 в 18:30.
Arkuz вне форума Ответить с цитированием
Старый 14.01.2020, 18:44   #7
archerix
Форумчанин
 
Регистрация: 13.09.2019
Сообщений: 119
По умолчанию

Просто так привычнее - я всю жизнь в Фортране и С массивы использовал, а тут все как-то не так И там и там такие файлы читаются одной строчкой и ничего парсить не надо.
До этих специфических форматов файлов дело вряд ли дойдет, скорее всего мне ничего не потребуется, кроме чтения чисел из тектового файла на 2-3 колонки.
archerix вне форума Ответить с цитированием
Старый 14.01.2020, 18:59   #8
Arkuz
Форумчанин
 
Аватар для Arkuz
 
Регистрация: 22.09.2007
Сообщений: 540
По умолчанию

Ну как вам будет удобнее.
Рекомендую посмотреть на CSV (https://python-scripts.com/import-csv-python).
Arkuz вне форума Ответить с цитированием
Старый 15.01.2020, 15:08   #9
ViktorR
Старожил
 
Регистрация: 23.10.2010
Сообщений: 2,304
По умолчанию

archerix
Цитата:
Просто так привычнее - я всю жизнь в Фортране и С массивы использовал
Возможно вы подумали, что список - это хороший тип для вашего массива, но это не так.
Список приспособлен для хранения разнородных типов данных и не очень эффективен при реализации массива однотипных данных.
У вас однотипные данные и поэтому вам нужны массивы.
Посмотрите в сторону модуля numpy.
Как-то так, ...
ViktorR вне форума Ответить с цитированием
Старый 15.01.2020, 16:57   #10
archerix
Форумчанин
 
Регистрация: 13.09.2019
Сообщений: 119
По умолчанию

Да нет, я так не подумал - был сильно удивлен, что в Питоне нет обычных массивов

Numpy обязательно надо будет поковырять, пока освоить хоть стандартные средства
archerix вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Считывание из файла чисел dimon_snake Общие вопросы C/C++ 7 29.01.2016 15:47
С++ Считывание чисел из файла с расширением .txt Gared Помощь студентам 2 18.09.2011 16:11
Считывание чисел из файла в массив rubakKa Общие вопросы C/C++ 11 02.12.2010 21:55
Считывание с файла отрицательных чисел trinki Общие вопросы C/C++ 2 01.10.2010 01:39