Что из этого является питоническим? и Pythonic vs. Speed ​​

Я новичок в python и только что написал эту функцию уровня модуля:

def _interval(patt):
    """ Converts a string pattern of the form '1y 42d 14h56m'
    to a timedelta object.
    y - years (365 days), M - months (30 days), w - weeks, d - days,
    h - hours, m - minutes, s - seconds"""

    m = _re.findall(r'([+-]?\d*(?:\.\d+)?)([yMwdhms])', patt)

    args = {'weeks': 0.0,
            'days': 0.0,
            'hours': 0.0,
            'minutes': 0.0,
            'seconds': 0.0}

    for (n,q) in m:
        if q=='y':
            args['days'] += float(n)*365
        elif q=='M':
            args['days'] += float(n)*30
        elif q=='w':
            args['weeks'] += float(n)
        elif q=='d':
            args['days'] += float(n)
        elif q=='h':
            args['hours'] += float(n)
        elif q=='m':
            args['minutes'] += float(n)
        elif q=='s':
            args['seconds'] += float(n)

    return _dt.timedelta(**args)

Моя проблема связана с циклом for , то есть длинным if elif block, и интересовался, есть ли более питонический способ сделать это.
Поэтому я переписал функцию следующим образом:

def _interval2(patt):

    m = _re.findall(r'([+-]?\d*(?:\.\d+)?)([yMwdhms])', patt)

    args = {'weeks': 0.0,
            'days': 0.0,
            'hours': 0.0,
            'minutes': 0.0,
            'seconds': 0.0}

    argsmap = {'y': ('days', lambda x: float(x)*365),
               'M': ('days', lambda x: float(x)*30),
               'w': ('weeks', lambda x: float(x)),
               'd': ('days', lambda x: float(x)),
               'h': ('hours', lambda x: float(x)),
               'm': ('minutes', lambda x: float(x)),
               's': ('seconds', lambda x: float(x))}

    for (n,q) in m:
        args[argsmap[q][0]] += argsmap[q][1](n)

    return _dt.timedelta(**args)

Я проверил время выполнения обоих кодов с помощью модуля timeit и обнаружил, что второй занимает примерно на 5-6 секунд больше (для количества повторов по умолчанию).

Итак мой вопрос:
1. Какой код считается более питоническим?
2. Есть ли еще более питонический способ написания этой функции?
3. Как насчет компромиссов между питонностью и другими аспектами программирования (например, скоростью в данном случае)?

ps У меня вроде есть ОКР для элегантного кода.

EDITED _interval2 после просмотра этот ответ :

argsmap = {'y': ('days', 365),
           'M': ('days', 30),
           'w': ('weeks', 1),
           'd': ('days', 1),
           'h': ('hours', 1),
           'm': ('minutes', 1),
           's': ('seconds', 1)}

for (n,q) in m:
    args[argsmap[q][0]] += float(n)*argsmap[q][1]

6
задан Community 23 May 2017 в 11:55
поделиться