#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()
функцию, я не вижу разумного способа сделать то, что вы хотите. Изменение вашей программы на объектно-ориентированную обычно требует, чтобы вы могли изменить свою программу, обычно довольно существенно.