0

I need help with a problem asking for lists of numbers (all of which are the same length) using the rule A[i] = A[i] * B[i] + C[i] at each index i. After this each A[i] if A[i] < 0 returns -1.0, otherwise it returns 1.0.

So far I have

def Vecombine(A, B, C):
    for i in range(len(A)):
        A[i] = A[i] * B[i] + C[i]
        return A[i]
    if A[i] < 0:
        return (-1.0)

I know I need to somehow add in another loop to keep track of the positive and negatives for what is eventually returned but I am just a little confused on how to do that. I also may be way off writing this code... I am trying but I just don't fully understand python.

icedwater
  • 4,701
  • 3
  • 35
  • 50

4 Answers4

2

You can use a list comprehension or generator for this

def Vecombine(a, b, c):
    return (-1.0 if i * j + k < 0 else 1.0 for i, j, k in zip(a, b, c))

Relevant documentation:

Edit: If you want to mutate a

def Vecombine(a, b, c):
    for i in xrange(len(a)):
        a[i] = -1.0 if a[i] * b[i] + c[i] < 0 else 1.0
DanielB
  • 2,798
  • 1
  • 19
  • 29
0
In [84]: %paste
def Vecombine(A,B,C):
  for i,(a,b,c) in enumerate(itertools.izip(A,B,C)):
    A[i] = a*b + c

## -- End pasted text --

In [85]: A = range(1,5)

In [86]: B = range(5,9)

In [87]: C = range(9,13)

In [88]: len(A)==len(B)==len(C)
Out[88]: True

In [89]: A
Out[89]: [1, 2, 3, 4]

In [90]: Vecombine(A,B,C)

In [91]: A
Out[91]: [14, 22, 32, 44]
inspectorG4dget
  • 110,290
  • 27
  • 149
  • 241
  • I like the use of `enumerate()`, I need to get used to this. But the original question called for a list of 1.0 or -1.0, as I understand it. – icedwater Oct 31 '13 at 05:00
0

I don't think this will work the way you think it will, for each A[i], it will just return from the function. You could replace A[i]'s value with -1.0 or 1.0 and return A in the end, but once the first index returns from the function, it's done. Also, unless it's formatted incorrectly, it will always return A[0]. Perhaps this is what you want.

def Vecombine(A,B,C):
    l = []
    for i in range(len(A)):
        A[i]=A[i] * B[i] + C[i]
    if A[i]<0:
        l.append(-1.0)
    else:
        l.append(1.0)
    return l

At the end of the function, l will have [-1.0, -1.0, 1.0, 1.0, etc...]

byee
  • 33
  • 4
  • I'm not sure this is what the OP actually wants, because the check `if A[i]<0:` is only executed once, *after* the loop is completed, on the last element of the array. It is equivalent to `if A[-1]<0:` If that is in fact what the OP wants, it should be made explicit by replacing `i` with `-1`. – SethMMorton Oct 31 '13 at 05:07
  • On second glance, it looks like you wanted the `if` statement to be *inside* the `for` loop. – SethMMorton Oct 31 '13 at 05:12
  • When I put the `if` statement inside the `for` loop is causes multiple failures in my program. The above program works except for `(A,B,C)= [1,2,3],[1,1,1],[-10,-20,-30]` it should return `-1.0` but it is returning `1.0` Do I need to add new loop so the check is executed more than once? – user2847983 Oct 31 '13 at 05:19
  • @user2847983 If a solution doesn't give you the answer you want, you shouldn't accept it. It discourages others from adding more answers that may be better/give you the correct answer. As I pointed out in my above comments, the logic in this solution is wrong... I think the `if` statement needs to be indented. – SethMMorton Oct 31 '13 at 15:23
0

Inspired by inspectorG4dget:

from itertools import izip
from math import copysign

def Vecombine(A, B, C):
""" Assuming A, B, C are lists of same length, process them and return
    1.0 if the result is positive or -1.0 if the result is negative. """
    for i, (a, b, c) in enumerate(izip(A, B, C)):
        A[i] = a * b + c
    S = [copysign(1, el) for el in A] 
    return (A, S)

I saved it in test.py. Then it was tested with the following values:

from test import Vecombine

a = [1, 3, 5, 7]
b = [-1, -1, 1, 1]
c = [0, 0, 0, 0]

print "a = ", a
print "b = ", b
print "c = ", c

(ans, sign) = Vecombine(a, b, c)

print "Answers: ", ans
print "Signs: ", sign

This overwrites your original array with the results of the calculation. S then holds the signs of the corresponding values in A, i.e. 1.0 for positive values and -1.0 for negatives using copysign.

** However, it seems to be overwriting the value of a with each run. This will need to be solved.

Community
  • 1
  • 1
icedwater
  • 4,701
  • 3
  • 35
  • 50