Создайте функцию, которая открывает файл и создает словарь

#python #function #dictionary

#python #функция #словарь

Вопрос:

У меня есть файл, с которым я работаю. Я хочу создать функцию, которая считывает файлы и помещает содержимое в словарь. Затем этот словарь необходимо передать через основную функцию. Вот основная программа. Она не может быть изменена. Все, что я делаю, должно работать с основной программой.

 def main():
    sunspot_dict = {}
    file_str = raw_input("Open what data file: ")
    keep_going = True
    while keep_going:
        try:
            init_dictionary(file_str, sunspot_dict)
        except IOError:
            print "Data file error, try again"
            file_str = raw_input("Open what data file: ")    
            continue
        print "Jan, 1900-1905:", avg_sunspot(sunspot_dict, (1900,1905),(1,1))
        print "Jan-June, 2000-2011:", avg_sunspot(sunspot_dict, (2000,2011), (1,6))
        print "All years, Jan:", avg_sunspot(sunspot_dict, month_tuple=(1,1))
        print "All months, 1900-1905:", avg_sunspot(sunspot_dict, year_tuple=(1900,1905))
        try:
            print "Bad Year Key example:", avg_sunspot(sunspot_dict, (100,1000), (1,1))
        except KeyError:
            print "Bad Key raised"
        try:
            print "Bad Month Index example:", avg_sunspot(sunspot_dict, (2000,2011), (1,100))
        except IndexError:
            print "Bad Range raised"
        keep_going = False
    print "Main function finished normally."

    print sunspot_dict
  

Вот что у меня есть на данный момент:

 def init_dictionary(file_str, sunspot_dict):
    line = open(file_str, "rU")
    sunspot_dict = {}
    for i in line:
        sunspot_dict[i]
print sunspot_dict
  

Комментарии:

1. @KarlKnechtel Я не уверен, как поступить. Возможно, я неправильно понимаю проблему. Вот что говорит назначение: init_dictionary(file_string, sunspot_dict). Эта функция принимает в качестве аргумента имя файла, который нужно открыть, и пустой словарь. Она не имеет возвращаемого значения, но заполняет словарь значениями. Ключом должен быть год; данные должны представлять собой список данных о солнечных пятнах за месяцы этого года. Говорится ли в нем об использовании функции init для выполнения этого в классе? Или я должен просто создать обычную функцию с именем init_dictionary(file_string, sunspot_dict)?

Ответ №1:

Основываясь на вашем втором комментарии и коде предварительного просмотра, вы на правильном пути. Словари в Python передаются по ссылке, поэтому вы должны просто иметь возможность заполнить словарь, предоставленный в init_dictionary , и значения будут доступны в main() . В вашем случае вы создаете новый словарь в init_dictionary с помощью строки sunspot_dict = {} . Вы не хотите этого делать, потому что словарь, который вы хотите использовать, уже был создан в main() .

На этом этапе нам нужно было бы знать формат файла, который вы читаете. По сути, вам нужно открыть файл, затем, вероятно, прочитать его построчно, разбирая строки на пары ключ / значение и заполняя sunspot_dict .

Комментарии:

1. Это просто текстовый файл. СРЕДНЕЕ КОЛИЧЕСТВО СОЛНЕЧНЫХ ПЯТЕН ЗА МЕСЯЦ ==================================================================== Год январь февраль Март Апрель май Июнь Июль август сентябрь Октябрь Ноябрь декабрь ——————————————————————— 1749 58.0 62.6 70.0 55.7 85.0 83.5 94.8 66.3 75.9 75.5 158.6 85.2 Я превратил годы в ключи, а цифры, следующие за ними, в значения. Теперь мне нужно удалить все, кроме цифр. Есть идеи о лучшем способе сделать это?

2. Оттуда мне нужно создать кортежи. Один для лет, а другой для месяцев. Это делается для того, чтобы пользователь вводил количество времени и получал среднее значение.

3. Вы написали avg_sunspot функцию? Похоже, что для этого требуется ваш словарь, затем два кортежа: один, который указывает диапазон лет для усреднения, а другой — диапазон месяцев. Если у вас возникли проблемы с написанием этой функции, вам следует задать новый вопрос.

4. Что касается вашего словаря, я думаю, вы близки к этому. В качестве ключа она должна использовать год, а затем иметь список чисел (их 12) для значения. Я не знаю, что вы подразумеваете под «удалить все, кроме цифр», но вы, вероятно, захотите использовать split() и float(str) .

5. Я смог выяснить, как получать только цифры, используя .isdigit() и помещая только эти значения в словарь. Что касается этой функции: avg_sunspot(sunspot_dict, year_tuple, month_tuple): она запрашивает 3 аргумента. Если кто-то приводит только два аргумента, я хочу, чтобы по умолчанию указывалось только среднее значение за все годы. Как мне установить значение по умолчанию?

Ответ №2:

Учитывая ограничение, которое вы даете в своем ответе Raymond, что вы не можете изменять init_dictionary() метод и что для этого требуется, чтобы вы передали ему словарь, который он затем заполнит, я рекомендую вам сделать свой собственный класс подклассом dict .

 class MySunspotDict(dict):
    def __init__(self, file_str):
        init_dictionary(file_str, self)

    # ... define your other methods here

sunspot_dict = MySunspotDict(file_str)
  

sunspot_dict = MySunspotDict(file_str) Строка идет туда, где у вас есть в данный момент init_dictionary(file_str, sunspot_dict) , поэтому ваша существующая file_str информация передается MySunspotDict конструктору ( __init__() методу), который затем передаст ее init_dictionary() .

init_dictionary() Вызов работает так же, как тот, который у вас уже есть, за исключением того, что он передает новый объект, а не пустой dict , функции, которая заполняет словарь. Поскольку ваш новый класс является производным от dict , то есть это подкласс, для этой цели он работает точно так же, как обычный словарь. Итак, у вас есть в основном dict , к которому вы можете присоединить свои собственные методы. (Вы также можете переопределить некоторые стандартные действия словаря, определив методы со специальными именами, но в данном случае вам не нужно этого делать.)

Обратите внимание, что в ваших методах self будет словарь — вам не нужно создавать словарь в вашем __init__() и сохранять его как атрибут вашего класса (вы увидите этот шаблон во многих кодах Python). Словарь уже существует ко времени __init__() выполнения.

Комментарии:

1. Поскольку основная функция запрашивает у пользователя имя файла, как я могу связать это с классом, который я создаю? Из вашего примера основная функция будет выходить за пределы класса MySunspotDict, верно? Можете ли вы объяснить мне следующую часть кода? инициализирующий словарь(file_str, self)

2. Добавлено некоторое дополнительное разъяснение.

3. «Строка sunspot_dict = MySunspotDict(file_str) идет туда, где у вас в данный момент есть init_dictionary(file_str, sunspot_dict)» Вы пытаетесь сказать, измените его из основной функции в цикле while? продолжая работу: попробуйте: init_dictionary(file_str, sunspot_dict), кроме IOError: я ничего не могу изменить в основной функции. Код, который я пишу, должен работать с основной функцией. Мне нужно прочитать файл, который пользователь вводит из функции main, и поместить данные в словарь.

4. Извините, если я не понимаю вашего объяснения. У меня просто много проблем с пониманием классов.

5. Упс, это моя ошибка. Я думал, вы не сможете изменить init_dicitonary() функцию. Если вы не можете изменить свою main() функцию, я не вижу разумного способа сделать то, что вы хотите. Изменение вашей программы на объектно-ориентированную обычно требует, чтобы вы могли изменить свою программу, обычно довольно существенно.