Python: Any optimized way to check that 2 lists increase together?
Let's assume we have 2 lists
a = [1,2,4,3,5] and
b = [103,122,800,500,1000]
is there an optimized way that I can check that they are "increasing together"?
My current solution, employs a loop:
for i in range(1,len(a)): if (a[i-1] < a[i] and b[i-1] > b[i]) or (a[i-1] > a[i] and b[i-1] < b[i]): print('wrong')
Is there a better way?
- The solution does not need to be list specific (really any data structure would work)
- The two iterables do not need to increase by the same number of units, just have to increase together.
You can't really get any faster than O(n), but you could make your code a bit shorter and maybe more readable by using
numpy.diff and comparing the
sign of the diffs of
>>> from numpy import diff, sign >>> a, b = [1,2,4,3,5], [103,122,800,500,1000] >>> sign(diff(a)) array([ 1, 1, -1, 1]) >>> all(sign(diff(a)) == sign(diff(b))) True >>> a, b = [1,2,4,3,5], [103,122,800,500,100] >>> all(sign(diff(a)) == sign(diff(b))) False
The downside of this solution is that it does not use lazy-evaluation, i.e. it calculates and compares the entire
sign(diff(...)) array even if the "increasingness" of
b differs in the very first position. If the list is very long, you should consider using another approach.
Python Compare Two Lists, and return a value based on the arguments passed. The cmp () function is a built-in method in Python used to compare the elements of two lists. The function is also used to compare two elements and return a value based on the arguments passed. This value can be 1, 0 or -1. Note: cmp () build to function for python version 2, In python version 3 it is not available.
In terms of O(order notation), you can't get better than linear, assuming lists don't have some order. But, you can use some python compiler like cython, numba to speed up your code. Your code using numba:
import numpy as np import numba as nb @nb.njit() def vary_together(a, b): for i in range(1,len(a)): if (a[i-1] < a[i] and b[i-1] > b[i]) or (a[i-1] > a[i] and b[i-1] < b[i]): return False return True
You have to use large lists to see the performance benefit. For example, if:
a = np.array([randint(0,100) for i in range(10000000)])
vary_together(a, a) # a as both arguments so as to make it complete the loop
Has has the performance comparison to your solution as :
Your solution: 8.09s vary_together: 0.2 (on second run to discount for compile time).
If you need to run the code again and again in the script, do
cache=True in the
How can I compare two ordered lists in python?, How do you check if two lists are identical in Python? Python | Intersection of two lists Intersection of two list means we need to take all those elements which are common to both of the initial lists and store them into another list. Now there are various ways in Python, through which we can perform the Intersection of the lists.
We can use the lazy evaluation provided by python iterators, meaning we don't need to continue traversing both lists ( structures ) once they don't have the same variation sign
def compare_variation( a, b ): a_variations = ( a[ i - 1 ] < a[ i ] for i in range( 1, len( a ) ) ) b_variations = ( b[ i - 1 ] < b[ i ] for i in range( 1, len( b ) ) ) return all( x == y for x, y in zip( a_variations, b_variations ) )
Difference Between Two Lists using Python Set & Without Set, or not, a == b should give you true / false with ordering taken into account. Here, c will contain an array with 3 elements all of which are true (for your example). The built-in Python sorting is stable, so the two 1 s don't cause a problem. >>> l1 = [3, 2, 4, 1, 1] >>> l2 = ['three', 'two', 'four', 'one', 'second one'] >>> zip(*sorted(zip(l1, l2))) [ (1, 1, 2, 3, 4), ('one', 'second one', 'two', 'three', 'four')] share. Share a link to this answer. Copy link. |.
Here is a way with list comprehension:
c = [(a[x + 1] - a[x]) * (b[x + 1] - b[x]) for x in range(len(a) - 1)] if any([x < 0 for x in c]): print('Wrong')
Comparing all the previous approaches (except for the numba one), tobias_k's answer looks like most efficient when dealing with large enough lists (at list 40 elements roughly).
Python, How do you compare two lists in python and return Non matches? Python extend () Vs append () If you need to add an element to the end of a list, you can use the append () method. a1 = [1, 2] a2 = [1, 2] b = (3, 4) # a1 = [1, 2, 3, 4] a1.extend (b) # a2 = [1, 2, (3, 4)] a2.append (b) To learn more, visit list append () method.
Python, This article deals with the task of ways to check if two unordered list contains exact similar elements in exact similar position, i.e to check if two lists are exactly equal. The first list is : [1, 2, 4, 3, 5] The second list is : [1, 2, 4, 3, 5] The lists are identical Python | Check if two lists have any element in common · Python | Check Python Functions: List comprehension, Map and Filter. To make a more broad comparison we will also benchmark against three built-in methods in Python: List comprehensions, Map and Filter. List comprehension: List comprehensions are known to perform, in general, better than for loops as they do not need to call the append function at each iteration.
Optimization tricks in Python: lists and tuples, Input : a = [1, 2, 3, 4, 5] b = [5, 6, 7, 8, 9] Output : True Input : a=[1, 2, 3, 4, Using traversal in two lists, we can check if there exists one common element at least in them. a positive integer, if it does not contains any positive integer, then it returns 0. Please Improve this article if you find anything incorrect by clicking on the When choosing a collection type, it is useful to understand the properties of that type. Choosing the right type for a particular data set could mean retention of meaning, and, it could mean an increase in efficiency or security. List. A list is a collection which is ordered and changeable. In Python lists are written with square brackets.
11. Lists, An overview of optimization tricks for lists and tuples. a = (1,2,3) >>> a = 10 Traceback (most recent call last): File When creating an empty tuple Python points to already preallocated one, in such way that any empty This over-allocates proportional to the list size, making room for additional growth. xrange is a generator object, basically equivalent to the following Python 2.3 code: def xrange (start, stop=None, step=1): if stop is None: stop = start start = 0 else: stop = int (stop) start = int (start) step = int (step) while start < stop: yield start start += step. Except that it is implemented in pure C.
- By optimize you want faster than current O(N)?
- What do you mean with "increasing together"? That the elements in both lists are sorted in increasing order? Or that element[i] in one list is bigger then element[i] in the other list for all possible indices? Something else?
- well there is the loop, and then there is the comparison operation itself. So really both. Looking whether I am oblivious to CS approach that has handled this more elegantly.
- You might get some improvement in performance by phrasing this in terms of numpy ndarrays.
- @quant what I mean is that regardless of initial sort of item that if element a[i] is larger than a[i-1] then the same is true for items at same indices in list b.
- I find this the most elegant, and it avoid an explicit loop. Thanks. It worked like a charm.
- Your approach is actually fastest when one compares two large lists which increase together.
- Good answer. But numba can look exotic for beginners. Add vary_together (a,ma) with ma=-a to enforce the lazy aspect. and compare with and without numba (4 cases)
- If you still calculate the
signfor the entire lists
b, lazy-evaluating whether they are equal does not lower the number of operations significantly, even if they differ in the very first comparison.
- @tobias_k valid point i have updated my code accordingly, thanks a lot
- You can just write
a[i-1] < a[i]instead of
True if a[ i - 1 ] < a[ i ] else False. Also, I'd suggest switching to Python 3, i.e. just use
zip, which now return iterators instead of lists.
- @tobias_k I have changed my code following your recommendations, thanks a loot
- @tobias_k totally forgot about the xrange, thanks a lot, much appreciated