2016-07-04 6 views
0

sagen, dass ich eine Liste der Daten, die unten in einem der fünf Arten formatiert werden:leistungsfähigere Way Termine für in Python für MySQL Format

Date_Type_1 = 2001 Apr 15 
Date_Type_2 = 2001 Apr 
Date_Type_3 = 2000 Spring 
Date_Type_4 = 2000 Nov-Dec 
Date_Type_5 = 2001 

Damit meine aktuelle Liste wie folgt aussehen.

Date_list = ["2001 Apr 15", "2004 May 15", "2011 Jan", "2011 Fall", "2000 Nov-Dec", "2012", "2000 Spring" ] 

Ich möchte jetzt versuchen, diese Daten zu formatieren, damit sie an eine MySQL-Datenbank übergeben werden können. Die einzige Art, wie ich weiß, ist, eine Menge Condition Flow zu verwenden. Hier ist ein Beispiel, wie ich das machen würde. Ich werde nicht ALLE Bedingungen einschließen, da es zu viel Platz beanspruchen würde.

for i in Date_list: 
    year = i[:4] 
    #This will be my conditional logic to define a month. 
    #This is only an example. Will not include all 12 months, 4 seasons, and various bi-months 
    if "Apr" in i and "Mar-Apr" not in i: 
    month = 4 
    if "Mar-Apr" in i: 
    month = 3 
    if "May" in i and "May-Jun" not in i: 
    month = 5 
    if "Apr-May" in i: 
    month = 4 
    if "Spring" in i: 
    month = 3 
    #This will be conditional logic to define the day. 
    #I would do this for each of the 31 days of the month. 
    if "15" in i and "2015" not in i: 
    day = 15 

date_return = datetime.datetime(year,month,day) 
date_format = date_return.date().isoformat 

Das Problem damit ist, dass ich eine Reihe von Annahmen mache. Ich bin damit einverstanden, Jahreszeiten zu definieren "Frühling/Sommer .." und die zweimonatlich (z. B. März/April) gibt als bestimmte Monate zurück. Das Problem, zumindest mit der Definition von Tagen ist, es wird nicht Tage fangen, wenn:

test_list = [2011 May, 2015 Apr 15] 
for i in test_list: 
    if "15" in i and "2015" not in i: 
    day = 15 

Dies wird nicht den Tag zu fangen. Ich frage mich, ob es einen effizienteren Weg gibt, dies zu tun? Diese aktuelle Methode würde mehr als 50 bedingte Anweisungen erfordern, um den Tag/die Monate zu definieren.

+0

Ich glaube nicht, dass Ihr Code langsam ist, aber sieht aus wie Ihre effiziente, kürzere Version. – YOU

+1

Beide sind gute Antworten und sehr elegant. Danke, ich wünschte, ich könnte beides auswählen. – Sean

Antwort

1

Sie den regulären Python Ausdruck Modul re verwenden soll. Es ist viel besser für diese als versuchen, mit Scheiben und in zu verwirren.

import re 

MONTHS = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 
    'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] 
SEASONS = { 'Spring': 'Mar', 'Summer': 'Jun', 'Fall': 'Sep', 
    'Autumn': 'Sep', 'Winter': 'Dec' } 

_MONTHS_RE = '|'.join(MONTHS) 
_SEASONS_RE = '|'.join(SEASONS) 
DATE_RE = re.compile(r"""(?ax) # ASCII-only verbose mode 
    (?P<year>20[0-9]{2}) # Year 
    (# followed by either... 
     (?P<month>""" + _MONTHS_RE + r""") # a month name then... 
     ( -(?P<endmonth>""" + _MONTHS_RE + r""") # a month range 
     | (?P<day>[1-9][0-9]?) # a day number 
     )? # range and day are optional 
    | (?P<season>""" + '|'.join(SEASONS) + r""") # or a season. 
    )""") 

def parse_date(datestr): 
    m = DATE_RE.match(datestr) 
    if m is None: 
     return # Didn't match 
    md = m.groupdict() 
    year = int(md["year"]) 
    if "season" in md: 
     month = SEASONS[md["season"]] 
    else: 
     month = md["month"] 
     if "endmonth" in md: 
      # handle month range here. 
     day = int(md.get("month", 1)) 
    return year, month, day 
    # Month is returned as a string; to get a number, use: 
    return year, MONTHS.index(month) + 1, day 

Beachten Sie, dass dies nicht gewährleistet, dass das Datum existiert; Es wird "2099 Jun 50" oder viele andere schlechte Daten akzeptieren. Aber ich lasse das als Übung für den Leser filtern.

1

Ich glaube, Sie es wie folgt tun:

>>> import datetime 
>>> dates = ["2001 Apr 15", "2004 May 15", "2011 Jan", "2011 Fall", "2000 Nov-Dec", "2012", "2000 Spring" ] 
>>> 
>>> def convert(date_str): 
...  tokens = date_str.split(' ') 
...  if len(tokens) == 1: 
...   date_time = datetime.datetime.strptime(date_str, '%Y') 
...  elif len(tokens) == 3: 
...   date_time = datetime.datetime.strptime(date_str, '%Y %b %d') 
...  elif len(tokens) == 2 and '-' in tokens[1]: 
...   date_str = date_str.split('-')[0] 
...   date_time = datetime.datetime.strptime(date_str, '%Y %b') 
...  else: 
...   seasons = { 
...    'spring': 'Mar', 
...    'fall': 'Sep', 
...   } 
...   if tokens[1].lower() in seasons.keys(): 
...    date_str = '{} {}'.format(tokens[0], seasons[tokens[1].lower()]) 
...   date_time = datetime.datetime.strptime(date_str, '%Y %b') 
...  return date_time.date().isoformat() 
... 
>>> 
>>> for date_str in dates: 
...  print '{} === {}'.format(date_str, convert(date_str)) 
... 
2001 Apr 15 === 2001-04-15 
2004 May 15 === 2004-05-15 
2011 Jan === 2011-01-01 
2011 Fall === 2011-09-01 
2000 Nov-Dec === 2000-11-01 
2012 === 2012-01-01 
2000 Spring === 2000-03-01