Naz
Naz

Reputation: 131

Perform math using elements from lists of lists with different lengths in Python

I have two (Lists of Lists) of different lengths (data_List, dataTwo_List) and I want to call the "funcX" function in a loop that iterates through both lists at the same time without producing the "List Out of Index" error using the size of data_List.

def funcX(x1, x2, y1, y2):
    return math.sqrt((x1-y1)**2 + (x2-y2)**2)

data_List = [[3, 4], [3, 6], [3, 8], [4, 5], [4, 7], [5, 1], [5, 5], [7, 3], [7, 5], [8, 5]]
dataTwo_List = [[5, 5], [3, 6], [7, 3]]

funcX(data_List[0][0],dataTwo_List[0][0],data_List[0][1],dataTwo_List[0][1])
funcX(data_List[1][0],dataTwo_List[0][0],data_List[1][1],dataTwo_List[0][1])
funcX(data_List[2][0],dataTwo_List[0][0],data_List[2][1],dataTwo_List[0][1])
funcX(data_List[3][0],dataTwo_List[0][0],data_List[3][1],dataTwo_List[0][1])
...
...
funcX(data_List[0][0],dataTwo_List[1][0],data_List[0][1],dataTwo_List[1][1])
funcX(data_List[1][0],dataTwo_List[1][0],data_List[1][1],dataTwo_List[1][1])
funcX(data_List[2][0],dataTwo_List[1][0],data_List[2][1],dataTwo_List[1][1])
funcX(data_List[3][0],dataTwo_List[1][0],data_List[3][1],dataTwo_List[1][1])
...
...

Upvotes: 1

Views: 58

Answers (2)

user7247147
user7247147

Reputation: 1107

Without itertools:

import math

def funcX(x1, x2, y1, y2):
    return math.sqrt((x1-x2)**2 + (y1-y2)**2)

data_List = [[3, 4], [3, 6], [3, 8], [4, 5], [4, 7], [5, 1], [5, 5], [7, 3], [7, 5], [8, 5]]
dataTwo_List = [[5, 5], [3, 6], [7, 3]]

i = 0
stop = len(dataTwo_List)
while i < stop:
  for list1 in data_List:
    funcX(list1[0], dataTwo_List[i][0], list1[1], dataTwo_List[i][1])
  i += 1

Upvotes: 1

SergioC
SergioC

Reputation: 159

You have two alternatives:

  1. zip(*iterables) function. Returns a zip object, which is an iterator of tuples where the first item in each passed iterator is paired together. If the passed iterators have different lengths, the iterator with the least items decides the length of the new iterator.

  2. itertools.zip_longest(*iterables, fillvalue=None) function. Make an iterator that aggregates elements from each of the iterables. If the iterables are of uneven length, missing values are filled-in with fillvalue.

Whatever the choice, the result is similar to:

import math

def funcX(x1, x2, y1, y2):
    return math.sqrt((x1-x2)**2 + (y1-y2)**2)

data_List = [[3, 4], [3, 6], [3, 8], [4, 5], [4, 7], [5, 1], [5, 5], [7, 3], [7, 5], [8, 5]]
dataTwo_List = [[5, 5], [3, 6], [7, 3]]

for ((x1, y1), (x2, y2)) in zip(data_List, dataTwo_List):
    funcX(x1, x2, y1, y2)

Update. I'm sorry, I did not finish seeing the result you wanted to obtain, I think this is what you wanted to get:

import math 
from itertools import product


def funcX(x1, x2, y1, y2):
    return math.sqrt((x1-x2)**2 + (y1-y2)**2)


data_List = [[3, 4], [3, 6], [3, 8], [4, 5], [4, 7], [5, 1], [5, 5], [7, 3], [7, 5], [8, 5]]
dataTwo_List = [[5, 5], [3, 6], [7, 3]]


for ((x2, y2), (x1, y1)) in product(dataTwo_List, data_List):
    funcX(x1, x2, y1, y2)

The product function return a iterator that generate the cartesian product between the two lists of elements. I put the dataTwo_List first to generate the same order that you want.

Upvotes: 3

Related Questions