[Python-ideas] List Revolution
Massimo Di Pierro
massimo.dipierro at gmail.com
Sat Sep 10 21:09:25 CEST 2011
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
>>> <massimo.dipierro at gmail.com> 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
>>>>> <massimo.dipierro at gmail.com> 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 at python.org
>>>>>>> http://mail.python.org/mailman/listinfo/python-ideas
>>>>>>
>>>>>> _______________________________________________
>>>>>> Python-ideas mailing list
>>>>>> Python-ideas at python.org
>>>>>> http://mail.python.org/mailman/listinfo/python-ideas
>>>>>>
>>>>
>>>> _______________________________________________
>>>> Python-ideas mailing list
>>>> Python-ideas at python.org
>>>> http://mail.python.org/mailman/listinfo/python-ideas
>>>>
>>>
>>>
>>>
>>> --
>>> --Guido van Rossum (python.org/~guido)
>>
>
More information about the Python-ideas
mailing list