2

I have an algorithmic question. Sorry if it seems to you silly.

Consider I have two lists:

list_a = ["Red", "Blue", "Black"]
list_b = ["Samsung", "Apple"]

So the question is, if I iterate through the lists above with two for loop is faster or merging them and using just one?

Ali Bahaari
  • 421
  • 2
  • 8
  • 4
    Does this answer your question? [How do I iterate through two lists in parallel?](https://stackoverflow.com/questions/1663807/how-do-i-iterate-through-two-lists-in-parallel) – Bhargav - Retarded Skills Apr 04 '23 at 11:56
  • 2 for loops is faster if you aren't nesting them(and also space efficient). – nice_dev Apr 04 '23 at 11:56
  • Also itertools library is written in C and is normally very fast, there are examples in the suggested duplicate. – Cow Apr 04 '23 at 11:57
  • Easy to find out: https://docs.python.org/3/library/timeit.html – Klaus D. Apr 04 '23 at 11:57
  • 2
    A good choice that combines efficiency and cleanness is [`itertools.chain`](https://docs.python.org/3/library/itertools.html#itertools.chain). – Jorge Luis Apr 04 '23 at 12:20

2 Answers2

2

Assuming that the goal is to just iterate elements of both collections (and not to produce and iterate some kind of Cartesian product) and if we are talking Big-O notation then from algorithmic point of view it does not matter - both will require O(m+n) (where m and n are length of list_a and list_b respectively) operations. The actual speed will be implementation specific, for example if you do something like list_a.extend(list_b) and then will iterate - then it will be slower due to the need to move elements (for simplicity we can consider it to be O(n)) but if you will be using some lazy iterable approach (for example itertools.chain as mentioned by @Jorge Luis) then the speed should be comparable.

In some cases you can "reduce" the Big-O to O(max(m, n)) by iterating them in one cycle for min(m, n) elements and then finishing the longer one in separate loop (pseudocode to get the idea):

longest = list_a if len(list_a) > len(list_b) else list_b

for i in range(min(len(list_a), len(list_b))):
    print(list_a[i])
    print(list_b[i])

for j in range(i+1, max(len(list_a), len(list_b))):
    print(longest[j])

Which is similar to what itertools.zip_longest does (as correctly mentioned by @chepner)

Guru Stron
  • 102,774
  • 10
  • 95
  • 132
0

Imho it depends on what you're trying to accomplish with the iteration.

If you need to perform an operation on each combination of elements from list_a and list_b, such as creating a Cartesian product or a nested loop, then using two for loops is necessary. In this case, merging the lists would not be useful and may even cause errors in your code.

However, if you just need to iterate over all the elements in both lists sequentially, then merging them into one list and using a single for loop would be faster and more efficient.

Mime
  • 66
  • 6
  • 1
    _"then merging them into one list and using a single for loop would be faster and more efficient."_ - can you please elaborate why? – Guru Stron Apr 04 '23 at 12:09
  • 2
    I have measured all the ways possible and merging seems to be up to 20% slower. – Jorge Luis Apr 04 '23 at 12:15
  • @GuruStron When you use two for loops, one for each list, you are essentially running two separate loops sequentially. Each loop has its own start and stop conditions, its own index variable, and its own set of iterations. This means that the computer has to perform more operations to keep track of the two loops separately, which can slow down the code. – Mime Apr 04 '23 at 12:20
  • 1
    I find it a bit of a cheat not to measure the time it takes to merge the two lists. – Jorge Luis Apr 04 '23 at 12:23
  • 3
    @Mime two combine two collections (unless you are using some lazy stuff like iterators, which can have it's own performance implications) you will need to iterate the second collection first and then iterate both. The "overhead" of having extra variable and extra jmp instructions is negligible compared. Either way you will need to perform m+n operations. – Guru Stron Apr 04 '23 at 12:24
  • Two (explicit) loops are not necessary for a Cartesian product; that's what `itertools.product` is for. – chepner Apr 04 '23 at 12:46