Re: [Python-ideas] List Revolution
On Sep 10, 2011, at 2:07 PM, Massimo Di Pierro wrote:
Not to open a can of worms but why not use eval in this example? It is faster. It is 5x more compact. It allows me to take advantage of the Python parser instead of reinventing the wheel. It is less error prone and easier to understand. It is a python keyword.
# with eval if not re.compile('^[\*\+\(\)\d]+$').match(name): raise AttributeError try: number = eval(name) except: raise AttributeError
# without eval tokenizer = re.compile('\+|\(\+|\(|\)|\*|[\d]+') stack = [0] while name: token = tokenizer.match(name) if not token: raise AttributeError elif token.group() in ('(','(+'): stack.append(0) elif token.group().isdigit(): stack.append(int(token.group())) elif token.group() in ')+' and len(stack)>1: stack[-2:]=[stack[-1]+stack[-2]] elif token.group()=='*': name = name[1:] token = tokenizer.match(name) if not token or not token.group().isdigit(): raise AttrbuteError stack[-1:]=[stack[-1]*int(token.group())] name = name[token.end():] number = sum(stack)
Massimo
On Sep 10, 2011, at 1:50 PM, Massimo Di Pierro wrote:
Of course. It was a proof of concept. Here is with an inline parser:
class List(list): """
a=List() for i in range(100000): a.append(i) print a.first 0 print a.second 1 print a.third 2 print a.twentieth 19 print a.twentysecond 21 print a.onehundredthirtyfifth 134 print a.onethousandfivehundredthirtyeighth 1537 """ def __getattr__(self,name): if name.endswith('first'): name = name[:-5]+'one' elif name.endswith('second'): name = name[:-6]+'two' elif name.endswith('third'): name = name[:-5]+'three' elif name.endswith('fth'): name = name[:-3]+'ve' elif name.endswith('hth'): name = name[:-3]+'th' elif name.endswith('ieth'): name = name[:-4]+'y' elif name.endswith('th'): name = name[:-2] subs = [ ("eleven","+11"), ("twelve","+12"), ("thirteen","+13"), ("fourteen","+14"), ("fiftheen","+15"), ("sixteen","+16"), ("seventeen","+17"), ("eighteen","+18"), ("nineteen","+19"), ("ten","+10"), ("twenty","+20"), ("thirty","+30"), ("fourty","+40"), ("fifty","+50"), ("sixty","+60"), ("seventy","+70"), ("eighty","+80"), ("ninety","+90"), ("one","+1"), ("two","+2"), ("three","+3"), ("four","+4"), ("five","+5"), ("six","+6"), ("seven","+7"), ("eigth","+8"), ("nine","+9"), ("ten","+10"), ("hundred",")*100+("), ("thousand",")*1000+("), ("million",")*1000000+("), ("billion",")*1000000000+("), ("trillion",")*100000000000+("), ("and","")] for key,value in subs: name = name.replace(key,value) if '(' in name: name='('+name+')' name.replace('()','1') ## parser import re tokenizer = re.compile('\+|\(\+|\(|\)|\*|[\d]+') stack = [0] while name: token = tokenizer.match(name) if not token: raise AttributeError if token.group() in ('(','(+'): stack.append(0) if token.group().isdigit(): stack.append(int(token.group())) if token.group() in ')+' and len(stack)>1: stack[-2:]=[stack[-1]+stack[-2]] if token.group()=='*': name = name[1:] token = tokenizer.match(name) if not token or not token.group().isdigit(): raise AttrbuteError stack[-1:]=[stack[-1]*int(token.group())] name = name[token.end():] number = sum(stack) ## end parser try: return self[number-1] except: raise IndexError
On Sep 10, 2011, at 1:00 PM, Guido van Rossum wrote:
I thought we were all just having a little bit of fun with what's obviously the least-likely-to-be-accepted proposal to have hit python-ideas in a long time; and now I see serious questions about it on Twitter and Quora... Time to start adding smileys to all posts! :-)
(Though seriously, Massimo, you should be able to implement the same idea without using eval() at all.)
--Guido
On Sat, Sep 10, 2011 at 10:50 AM, Massimo Di Pierro
wrote: Anyway ... mine was not a serious proposal. I like python lists as they are.
On Sep 10, 2011, at 12:43 PM, Devin Jeanpierre wrote:
Damn dollar signs. if not re.compile('^[\d\+\*\(\)]+$').match(name): return AttributeError
'(2**1024)**(2**1024)' etc.
Devin
On Sat, Sep 10, 2011 at 1:05 PM, Massimo Di Pierro
wrote: LOL.
Damn dollar signs. if not re.compile('^[\d\+\*\(\)]+$').match(name): return AttributeError
On Sep 10, 2011, at 11:45 AM, Stefan Behnel wrote:
> Massimo Di Pierro, 10.09.2011 18:35: >> [...] >> if not re.compile('[\d\+\*\(\)]+').match(name): return AttributeError >> [...] >> I would like to stress that the use of eval in this case is safe as the expression is first validated against a regex. > > Nice try. And it would even be ok if you had assured that the *entire* expression was validated against the regex. > > Stefan > > _______________________________________________ > Python-ideas mailing list > Python-ideas@python.org > http://mail.python.org/mailman/listinfo/python-ideas
_______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
_______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
-- --Guido van Rossum (python.org/~guido)
participants (1)
-
Massimo Di Pierro