[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