开发者

Help with inner loop in Python method

开发者 https://www.devze.com 2023-04-07 04:45 出处:网络
I\'m having trouble understand开发者_JS百科ing why an inner loop in my method isn\'t producing the desired behavior I\'m expecting and I\'m hoping someone can help me understand the problem.

I'm having trouble understand开发者_JS百科ing why an inner loop in my method isn't producing the desired behavior I'm expecting and I'm hoping someone can help me understand the problem.

My method takes a series of arguments (*args) and if the argument is an integer I want to add dollar signs around the integer (eg. $5$).

def t_row(*args):
    columns = 5
    if len(args) == columns:
        count = 0
        for value in args: 
            if type(value) is int:
                value = ''.join(('$', str(value), '$'))
            count += 1
            if count < len(args):
                penult_args = args[:-1]
                line_prefix = [''.join((str(value), " & ")) for value in penult_args]
            elif count == len(args):
                line_suffix = [''.join((str(value), " \\\\", "\n"))]
        count += 1
        line_list = line_prefix + line_suffix 
        line = ''.join(item for item in line_list)
        return(line)

The above code is used like this:

>>> s = q.t_row('data1', 'data2', 3, 'data4', 5)  
>>> print s  
data1 & data2 & 3 & data4 & $5$ \\  

Why don't I get dollar signs around the integer 3? How can I fix my code to correct this problem?


Because on this line:

            line_prefix = [''.join((str(value), " & ")) for value in penult_args]

you pull the values out of the original list (minus the last item), while on this line:

            value = ''.join(('$', str(value), '$'))

You added $ but never stored the value back into the list.

The 5 only gets $ because it's the last item, so you reference it directly in:

            line_suffix = [''.join((str(value), " \\\\", "\n"))]

A better way to do all this is:

def t_row(self, *args):
    if len(args) == self.columns:
        result = []
        for value in args:
            if isinstance(value, int):
                result.append('$%d$' % value)
            else:
                result.append(value)
        return ' $ '.join(result) + r' \\'

As a one-liner, it would be

t_row = lambda self, *args: (' $ '.join('$%d$' % 
          value if isinstance(value, int) else value for value in args) + r' \\' 
              if len(args) == self.columns else None)

but that's not actually a good idea.


The problem is because in this line:

line_prefix = [''.join((str(value), " & ")) for value in penult_args]

You are overwriting value with the original (non-dollar-signed) value.

It works for the last argument only because the above line is not called for args[-1].

Use a different variable name for your loop.

(Python's scoping is only within functions and classes, for loops and if statements are not independently scoped.)

0

精彩评论

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

关注公众号