3

A program I'm using at work uses Python as a scripting language. I am perplexed in my attempts to modify a list while interating over it. Also, I have some logic inside the for loop that I would like to convert portions of the list from floats to text. In the end all the text have to be exactly 4 spaces. In my research to solve this problem I have come accross numerous simular problems for other people attempting to modify a list while iterating over it. However I feel my issue is unique because I am attempting to modify the list from floats to text while iterating over it.

I actually found a work around for the problem but I feel the solution was more complicated then it needed to be and I'm looking for a more simple solution which is the reason why I'm here. I would like to improve the code.

Here is the code which is giving me problems:

#these come in as floats with a single decimal space, ex:99.9
val = [AvailibilityLine1, AvailibilityLine2,
       PerformanceLine1, PerformanceLine2,
       QualityLine1, QualityLine2]

for i in val:
    j = 0
    if i >= 100:
       val[j] = "100 "                                                           
    elif i >= 10 and i < 100:
       val[j] = str(val)
    elif i > 0 and  i < 10:
       val[j] = " " + str(val)
    elif i <= 0:
       val[j] = "    "    #insert 4 spaces
    else:
       val[j] = "    "    #insert 4 spaces if all else fails
    j=j+1
Patrick Bard
  • 1,804
  • 18
  • 40
ForgottenKahz
  • 268
  • 3
  • 24
  • 2
    can you put some test data... like for some test input what should be the expected output? – anuragal Feb 12 '14 at 04:55
  • I think its better to loop over the range of the length of the list, or list[:], if you need modification inside the iteration. In your current situation, its ok you didn't delete any element, but in future if you delete an element while iteration may end up with unwanted result. – James Sapam Feb 12 '14 at 05:17
  • Also check generators... – Jimmy Kane Feb 12 '14 at 08:47

5 Answers5

1

you can access and change the list value using index following way:

val= [1,2,3,4,5,6,50,110]
for i in xrange(len(val)):
    if val[i] >= 100:
       val[i] = "100 "                                                           
    elif val[i] >= 10 and val[i] < 100:
       val[i] = str(val[i])
    elif val[i] > 0 and  val[i] < 10:
       val[i] = " " + str(val[i])
    elif val[i] <= 0:
       val[i] = "    "    #insert 4 spaces
    else:
       val[i] = "    "    #insert 4 spaces if all else fails

print val
venpa
  • 4,268
  • 21
  • 23
0

This should work

AvailibilityLine1 = 1.9
AvailibilityLine2 = 45.9
PerformanceLine1 = 76.5
PerformanceLine2 = 99.9
QualityLine1 = 100.0
QualityLine2 = 0.0

#these come in as floats with a single decimal space, ex:99.9
val = [AvailibilityLine1, AvailibilityLine2, PerformanceLine1, 
       PerformanceLine2, QualityLine1, QualityLine2] 

j = 0
for i in val:
    if i >= float(100):
        val[j] = "100 "
    elif i >= 10 and i < 100:
        val[j] = str(val[j])
    elif i > 0 and  i < 10:
        val[j] = " " + str(val[j])
    elif i <= 0:
        val[j] = "    "    #insert 4 spaces
    else:
        val[j] = "    "    #insert 4 spaces if all else fails
    j = j + 1

print val

Output

>>> [' 1.9', '45.9', '76.5', '99.9', '100 ', '    ']

problems in your code:

  1. Initialization of counter J should be outside the for loop
  2. You are assigning whole list (val) to list index in 2nd and 3rd condition of if-else
anuragal
  • 3,024
  • 19
  • 27
0
def formatter(vals):
    def clamp(x):
        '''Fixes the values between 0 and 100'''
        return max(0, min(100, x))

    def string_formatter(x):
        '''Formats the values into a string with width 4'''
        if x == 100:
            return "{:<4g}".format(x)
        elif x == 0:
            return ' '*4
        else: 
            return "{:>4.1f}".format(x)

    return [string_formatter(clamp(i)) for i in vals]
M4rtini
  • 13,186
  • 4
  • 35
  • 42
0

Check out the use of the format command used for string formatting before continuing. This shoud allow you to safely convert any input to the format you need. The only thing here is that you need conditional formatting. Which means that the format string should be dependent upon the number that is formatting. This can easily be done like so:

fmtStr = lambda x: ' 100' if x >= 100 else ('    ' if x < 0 else '{:4.1f}')

This is a function that takes a number and returns a different format string depending upon the value it is given. Now given this value, all you need to do is to format every element in the list that you have. Easiest and the most Pythonic way is to do a list comprehension. So let us generate a list, and format it ...

vals    = random.random(103)*300 - 150
strVals = [fmtStr(i).format(i) for i in val]

Hope this helps.

ssm
  • 5,277
  • 1
  • 24
  • 42
0

You can use enumerate and string formatting to achieve this:

num_list = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
for _index, _value in enumerate(num_list):
    if val <= 0:
        _value = ""  # If value is 0 or lower, just change it to empty string
    elif val >= 100
        _value = 100  # If value is greater than or equal to 100.0, make it 100
    num_list[_index] = "{:>4}".format(_value)

>> num_list
>> [' 1.0', ' 2.0', ' 3.0', ' 4.0', ' 5.0', ' 6.0']

In format, "{:<4}" defines the text formatting, < means align text to left while, > means align it right and ^ means center it. 4 defines the final length. It apply the preferred alignment and fill the rest with spaces. If you want to use a filling character instead of spaces, you can use it like

num_list[_index] = "{:*<4}".format(_value)

>> num_list
>> ['1.0*', '2.0*', '3.0*', '4.0*', '5.0*', '6.0*']

Where * is your fill character

Mp0int
  • 18,172
  • 15
  • 83
  • 114