how to iterate over sequence and non-sequence ?

Nils nils.lastein at gmail.com
Fri Oct 19 07:37:24 EDT 2007


On Oct 19, 10:58 am, Steven D'Aprano
<ste... at REMOVE.THIS.cybersource.com.au> wrote:
> On Fri, 19 Oct 2007 01:24:09 +0200, stef mientki wrote:
> > hello,
>
> > I generate dynamically a sequence of values, but this "sequence" could
> > also have length 1 or even length 0.
>
> > So I get some line in the form of:
> >       line = '(2,3,4)'
> >       line = ''
> >       line = '(2)'
> > (in fact these are not constant numbers, but all kind of integer
> > variables, coming from all over the program, selected from a tree, that
> > shows all "reachable" variables)
>
> > So in fact I get the value from an exec statement, like this
> >       exec 'signals = ' + line
>
> And then, one day, somebody who doesn't like you will add the following
> to your input data:
>
> "0; import os; os.system('rm # -rf /')"
>
> [ Kids: don't try this at home! Seriously, running that command will be
> bad for your computer's health. Or at least it would, if I hadn't put a
> spike in it. ]
>
> Don't use exec in production code unless you know what you're doing. In
> fact, don't use exec in production code.
>
> > Now I want to iterate over "signals", which works perfect if there are 2
> > or more signals,
> > but it fails when I have none or just 1 signal.
> >     for value in signals :
> >         do something
>
> No, I would say it already failed before it even got there.
>
> >>> line = ''
> >>> exec 'signals = ' + line
>
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
>   File "<string>", line 1
>     signals =
>             ^
> SyntaxError: unexpected EOF while parsing
>
> This is the right way to deal with your data:
>
> input_data = """  (2, 3  , 4)
>
>   (2)
> (3,4,5)
> ( 1, 2,3)
> """
>
> for line in input_data.split('\n'):
>     line = line.strip().strip('()')
>     values = line.split(',')
>     for value in values:
>         value = value.strip()
>         if value:
>             print(value)
>
> > As this meant for real-time signals, I want it fast, so (I think) I
> > can't afford extensive testing.
>
> Don't guess, test it and see if it is fast enough. Some speed ups:
>
> If you're reading from a file, you can just say: "for line in file:"
> instead of slurping the whole lot into one enormous string, then
> splitting over newlines.
>
> If you can guarantee that there is no extra whitespace in the file, you
> can change the line
>
>     line = line.strip().strip('()')
>
> to the following:
>
>     line = line.strip('\n()')
>
> and save a smidgen of time per loop. Likewise, drop the "value =
> value.strip()" in the inner loop.
>
> --
> Steven.

why not:
>>> for i in eval('(1,2,3)'):
...     print i
1
2
3




More information about the Python-list mailing list