#python #python-3.x #dictionary
Вопрос:
У меня есть вложенный словарь, содержащий даты и соответствующие им типы объектов (не такие объекты, как в программировании), который выглядит следующим образом:
dict1 = {0: {'date': ['01', 'MAY', '14', '11MAY', '14', '18', 'MAY', '14'],
'objecttype': ['Table', 'Anything', 'Chair']},
1: {'date': ['12', 'MAY', '14', '12MAY14', '15MAY', '14'],
'objecttype': ['Cup', 'Chair', 'fan']},
2: {'date': ['05', 'MAY', '14', '13MAY14', '16MAY', '14'],
'objecttype': ['Home', 'Desk', 'Pencil']},
3: {'date': ['14', 'MAY', '14', '14MAY', '14', '04MAY14'],
'objecttype': ['Cup', 'Stationery', 'Book']},
4: {'date': ['15', 'MAY', '14', '15MAY14', '01', 'MAY', '14'],
'objecttype': ['Eraser', 'Pen', 'Notebook']}}
Все даты и объекты имеют ключи uniques, такие как 0-4.
Как видно, большинство дат не в правильном формате, и для нас правильный формат — [День][Месяц][Год], выглядит так:
04 МАЯ 14
Мой подход к решению этой проблемы заключается в использовании регулярных выражений и двойном циклическом переборе дат. на первом этапе я хочу найти все значения дат, где я нахожу только две цифры, подобные этой, например «04», и объединить их со следующим значением в списке, если он содержит только три алфавита, таких как этот «МАЙ». После этого шага большинство значений даты в dict будут выглядеть так [День][Месяц] .
04 МАЯ
В следующем цикле я хочу найти все экземпляры даты, в которых у нас есть только день и месяц, и объединить их со следующим значением в списке, которое должно быть значением года с двумя цифрами, чтобы в конечном итоге у нас были все даты в этом формате:
04 МАЯ 14
Окончательный диктант будет выглядеть так:
dict1 = {0: {'date': ['01MAY14', '11MAY14', '18MAY14'],
'objecttype': ['Table', 'Anything', 'Chair']},
1: {'date': ['12MAY14', '12MAY14', '15MAY14'],
'objecttype': ['Cup', 'Chair', 'fan']},
2: {'date': ['05MAY14', '13MAY14', '16MAY14'],
'objecttype': ['Home', 'Desk', 'Pencil']},
3: {'date': ['14MAY14', '14MAY14', '04MAY14'],
'objecttype': ['Cup', 'Stationery', 'Book']},
4: {'date': ['15MAY14', '15MAY14', '01MAY14'],
'objecttype': ['Eraser', 'Pen', 'Notebook']}}
У меня возникли проблемы с реализацией этого в python, буду признателен, если кто-нибудь сможет мне помочь. Спасибо
Комментарии:
1. обновил свой ответ.
Ответ №1:
Вы можете использовать дату и время вместо регулярного выражения:
from datetime import datetime
datetime_object = datetime.strptime('01MAY14', '%d%b%y')
print(datetime_object.strftime('%d/%m/%Y'))
#01/05/2014
Более длинный ответ:
def get_date(d):
if len(d) == 7:
return datetime.strptime(d, '%d%b%y')
else:
return datetime.strptime(d, '%d%b')
def get_year(l):
years = list()
for d in l:
y = get_date(d).year
if y and (y not in years) and (y != 1900):
years = [get_date(d).year]
return next(iter(years))
def get_date_with_year(d, y):
if len(d) == 7:
return datetime.strptime(d, '%d%b%y')
else:
return datetime.strptime(d str(y), '%d%b%Y')
def get_fixed_dates(l):
year = get_year(l)
return [get_date_with_year(d, year) for d in l]
l = '9MAY', '12MAY', '15MAY14'
print(get_fixed_dates(l))
#[datetime.datetime(2014, 5, 9, 0, 0), datetime.datetime(2014, 5, 12, 0, 0), datetime.datetime(2014, 5, 15, 0, 0)]
Для применения ко всем диктантам:
def helper(dic):
dic['date'] = get_fixed_dates(dic['date'])
return dic
new_dict = {k: helper(v) for k, v in dict.items()}
Комментарии:
1. В конце концов, таков план, но сначала я должен привести все разбитые даты в формат «01 МАЯ 14». обряд теперь все перепутал.
2. Спасибо, как я могу использовать его для своей проблемы, чтобы он применял функцию для каждого значения даты в словаре. Приношу извинения за вопрос noob, я новичок в словарях.
3. @AliZia обновлено, кстати. это плохая практика-повторно объявлять чистые функции python, например,
dict
с помощью вашего собственногоdict = something
использования d = … или чего-то уникального4. Я думаю, что случай, когда мы находим только значение дня, например «12», упущен. поэтому я получаю ошибку: ошибка значения: данные о времени » 12 «не соответствуют формату» %d%b»
5. Или, может быть, в моих данных есть ненужные значения. Вот почему я хотел пойти с регулярным выражением. но я ценю ваше время и помощь.
Ответ №2:
Сначала вы можете отделить значения цифр от месяца в тексте, а затем перегруппировать:
import re
def to_dates(d):
r = [i for a in d for i in re.findall('d |[a-zA-Z] ', a)]
return [''.join(r[i:i 3]) for i in range(0, len(r), 3)]
dict1 = {0: {'date': ['01', 'MAY', '14', '11MAY', '14', '18', 'MAY', '14'], 'objecttype': ['Table', 'Anything', 'Chair']}, 1: {'date': ['12', 'MAY', '14', '12MAY14', '15MAY', '14'], 'objecttype': ['Cup', 'Chair', 'fan']}, 2: {'date': ['05', 'MAY', '14', '13MAY14', '16MAY', '14'], 'objecttype': ['Home', 'Desk', 'Pencil']}, 3: {'date': ['14', 'MAY', '14', '14MAY', '14', '04MAY14'], 'objecttype': ['Cup', 'Stationery', 'Book']}, 4: {'date': ['15', 'MAY', '14', '15MAY14', '01', 'MAY', '14'], 'objecttype': ['Eraser', 'Pen', 'Notebook']}}
new_dict = {a:{**b, 'date':to_dates(b['date'])} for a, b in dict1.items()}
Выход:
{0: {'date': ['01MAY14', '11MAY14', '18MAY14'], 'objecttype': ['Table', 'Anything', 'Chair']},
1: {'date': ['12MAY14', '12MAY14', '15MAY14'], 'objecttype': ['Cup', 'Chair', 'fan']},
2: {'date': ['05MAY14', '13MAY14', '16MAY14'], 'objecttype': ['Home', 'Desk', 'Pencil']},
3: {'date': ['14MAY14', '14MAY14', '04MAY14'], 'objecttype': ['Cup', 'Stationery', 'Book']},
4: {'date': ['15MAY14', '15MAY14', '01MAY14'], 'objecttype': ['Eraser', 'Pen', 'Notebook']}}