开发者

Smart Loop List Creation in Python for Django Choice fields

So. The following isn't very 'smart' ;)

MONTHS = (
    ('Jan', 'Jan'),
    ('Feb', 'Feb'),
    ('Mar', 'Mar'),
    ('Apr', 'Apr'),
    ('May', 'May'),
    ('Jun', 'Jun'),
    ('Jul', 'Jul'),
    ('Aug', 'Aug'),
    ('Sep', 'Sep'),
    ('Oct', 'Oct'),
    ('Nov', 'Nov'),
    ('Dec', 'Dec'),
)

YEARS = (
    ('1995', '1995'),
  开发者_如何学Go  ('1996', '1996'),
    ('1997', '1997'),
    ('1998', '1998'),
    ('1999', '1999'),
    ('2000', '2000'),
    ('2001', '2001'),
    ('2002', '2002'),
    ('2003', '2003'),
    ('2004', '2004'),
    ('2005', '2005'),
    ('2006', '2006'),
    ('2007', '2007'),
    ('2008', '2008'),
    ('2009', '2009'),
    ('2010', '2010'),
)

I'm newer to python, and would love to produce stuff like this 'pythonically'.

Such as,

  • a list of year tuples from 1995 to current year.
  • a list of the abbreviated months of the year

Thanks Stackers'


In [17]: from datetime import datetime

In [18]: tuple((str(n), str(n)) for n in range(1995, datetime.now().year + 1))
Out[18]:
(('1995', '1995'),
 ('1996', '1996'),
 ('1997', '1997'),
 ('1998', '1998'),
 ('1999', '1999'),
 ('2000', '2000'),
 ('2001', '2001'),
 ('2002', '2002'),
 ('2003', '2003'),
 ('2004', '2004'),
 ('2005', '2005'),
 ('2006', '2006'),
 ('2007', '2007'),
 ('2008', '2008'),
 ('2009', '2009'),
 ('2010', '2010'))

In [19]: import calendar

In [20]: tuple((m, m) for m in calendar.month_abbr[1:])
Out[20]:
(('Jan', 'Jan'),
 ('Feb', 'Feb'),
 ('Mar', 'Mar'),
 ('Apr', 'Apr'),
 ('May', 'May'),
 ('Jun', 'Jun'),
 ('Jul', 'Jul'),
 ('Aug', 'Aug'),
 ('Sep', 'Sep'),
 ('Oct', 'Oct'),
 ('Nov', 'Nov'),
 ('Dec', 'Dec'))


Try using zip() to make a list of two-tuples.

MONTHS = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec')
somemonth = models.TextField(max_length=3, choices=zip(MONTHS,MONTHS))

choices will be set to [('Jan', 'Jan'), ('Feb', 'Feb'), ...].


In response to the comments on this answer, the "tuple" list comprehension version would be:

tuple((m, m) for m in MONTHS)

Versus the zip version:

tuple(zip(MONTHS, MONTHS))

But strictly speaking, Django doesn't need a tuple of choices, so:

zip(MONTHS, MONTHS)


See module time.

>>> import time

For the months we can use strptime to turn a month number 1-12 into a struct_time, and then use strftime to pull the month name out.

>>> [time.strftime('%b', time.strptime(str(i), '%m')) for i in range(1, 13)]
['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']

The years are more straightforward, we just need to know the current year (plus one, due to the way range works).

>>> [str(i) for i in range(1995, time.localtime().tm_year + 1)]
['1995', '1996', '1997', '1998', '1999', '2000', '2001', '2002', '2003', '2004', '2005', '2006', '2007', '2008', '2009', '2010']

I added str(i) to have the years returned as strings since that's the way you wrote them. If integers are okay then you can drop the whole list comprehension and simply use range(...).


import datetime
from django.db import models
from django.utils.dates import MONTHS


class MyCoolModel(models.Model):
    YEARS = YEARS = [(i,)*2 for i in range(1995, datetime.today().year + 1)]

    month = models.PositiveSmallIntegerField(choices=MONTHS.items())
    year = models.PositiveIntegerField(choices=YEARS)


Although some of the other answers might be "smarter", I dislike the idea of using a loop to define a tuple. Perhaps the following is a more readable compromise :

MONTHS = (
    ('Jan',) * 2,
    ('Feb',) * 2,
    ('Mar',) * 2,
    ('Apr',) * 2,
    ('May',) * 2,
    ('Jun',) * 2,
    ('Jul',) * 2,
    ('Aug',) * 2,
    ('Sep',) * 2,
    ('Oct',) * 2,
    ('Nov',) * 2,
    ('Dec',) * 2,
)

YEARS = (
    ('1995',) * 2,
    ('1996',) * 2,
    ('1997',) * 2,
    ('1998',) * 2,
    ('1999',) * 2,
    ('2000',) * 2,
    ('2001',) * 2,
    ('2002',) * 2,
    ('2003',) * 2,
    ('2004',) * 2,
    ('2005',) * 2,
    ('2006',) * 2,
    ('2007',) * 2,
    ('2008',) * 2,
    ('2009',) * 2,
    ('2010',) * 2,
)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜