0

My program has two lists of numbers. What I want to do is to iterate over the zip list obtained doing zip(), apply two different functions on the two intermediate variables and save the first result (apply compute_add()) in one list and the second (apply compute_sub()) in another. I can do it iterating two times on the zip list but I'm wondering if there is a way to do so in one shot.
Here is my code, of course is not running.

def compute_add(_x, _y):
    return _x * _y + 10


def compute_sub(_x, _y):
    return _x * _y - 10


list1 = [1, 2, 3, 4, 5]
list2 = [10, 20, 30, 40, 50]

res1, res2 = [compute_add(x, y), compute_sub(x, y) for x, y in zip(list1, list2)]

Any suggestions?

Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
User
  • 806
  • 1
  • 11
  • 28

5 Answers5

3

Assuming you want the sums in one list and the differences in another, there isn't a straightforward way to do that with a list comprehension. You could collect the pairs in a tuple and then split back up into two lists:

tup = [(compute_add(x, y), compute_sub(x, y)) for x, y in zip(list1, list2)]
res1 = [t[0] for t in tup]
res2 = [t[1] for t in tup]

With just a single loop over the zip, I would simply do

res1 = []
res2 = []
for x, y in zip(list1, list2):
    res1.append(compute_add(x,y))
    res2.append(compute_sub(x,y))

If the functions are genuinely this simple, of course, you can factor out the multiplication:

for x, y in zip(list1, list2):
    mul = x * y
    res1.append(mul + 10)
    res2.append(mul - 10)

For what it's worth, What is the inverse function of zip in python? has a nice answer to "how can I do the reverse of zip()" but it effectively traverses the list two times as well.

tripleee
  • 175,061
  • 34
  • 275
  • 318
1

Method 1: using list-comprehensions

def compute_add(_x, _y):
    return _x * _y + 10
def compute_sub(_x, _y):
    return _x * _y - 10

list1 = [1, 2, 3, 4, 5]
list2 = [10, 20, 30, 40, 50]
res1 = [compute_add(x, y) for x, y in zip(list1, list2)]
res2 = [compute_sub(x, y) for x, y in zip(list1, list2)]

print(res1) # [20, 50, 100, 170, 260]
print(res2) # [0, 30, 80, 150, 240]

Method 2: using for loop

You can simply iterate over the zip list obtained and apply directly your defined functions. See the above code.

def compute_add(_x, _y):
    return _x * _y + 10
def compute_sub(_x, _y):
    return _x * _y - 10

list1 = [1, 2, 3, 4, 5]
list2 = [10, 20, 30, 40, 50]
res1 = []
res2 = []
for x, y in zip(list1, list2):
    res1.append(compute_add(x, y))
    res2.append(compute_sub(x, y))

print(res1) # [20, 50, 100, 170, 260]
print(res2) # [0, 30, 80, 150, 240]
codrelphi
  • 1,075
  • 1
  • 7
  • 13
1

You can add the results to two list during the iteration

res1 = []
res2 = []
[[res1.append(compute_add(x, y)), res2.append(compute_sub(x, y))] for x, y in zip(list1, list2)]

print(res1, res2) # [20, 50, 100, 170, 260] [0, 30, 80, 150, 240]
Guy
  • 46,488
  • 10
  • 44
  • 88
  • 1
    This is a bit of an abuse of list comprehensions, though; you are using the comprehension for side effects, and throwing away the thing it actually *does.* – tripleee Jan 09 '20 at 09:26
1

Try using zip:

res1, res2 = zip(*[(compute_add(x, y), compute_sub(x, y)) for x, y in zip(list1, list2)])
U13-Forward
  • 69,221
  • 14
  • 89
  • 114
0

just change the code like this

res1, res2 = [[compute_add(x, y) for x, y in zip(list1, list2)], [compute_sub(x, y) for x, y in zip(list1, list2)]]