Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

List comprehension iterating over two lists is not working as expected [duplicate]

I want to iterate over two lists. The first list contains some browser user-agents and the second list contains versions of those browsers. I want to filter out only those user-agents whose version is greater than 60.

Here is how my list comprehension looks:

[link for ver in version for link in useragents if ver > 60]

The problem with this list is that it prints same user-agent multiple times. I wrote the following using the zip function, which works fine:

for link, ver in zip(useragents, version):
    if ver > 60:
        # append to list
        print(link)

Why is my list comprehension returning unexpected results?

like image 454
Viktor Avatar asked Jan 29 '19 12:01

Viktor


People also ask

Can you iterate through two lists simultaneously Python?

Use the izip() Function to Iterate Over Two Lists in Python It iterates over the lists until the smallest of them gets exhausted. It then zips or maps the elements of both lists together and returns an iterator object. It returns the elements of both lists mapped together according to their index.

Does list comprehension return a new list?

List comprehensions are used for creating new lists from other iterables. As list comprehensions return lists, they consist of brackets containing the expression, which is executed for each element along with the for loop to iterate over each element.

How much faster are list comprehensions than for loops?

As we can see, the for loop is slower than the list comprehension (9.9 seconds vs. 8.2 seconds). List comprehensions are faster than for loops to create lists. But, this is because we are creating a list by appending new elements to it at each iteration.


1 Answers

Your first list comprehension is equivalent to:

res = []
for ver in version:
    for link in useragents:
        if ver > 60:
            res.append(link)

Notice you have nested loop with time complexity O(n2), i.e. you are iterating over every combination of version and useragents. That's not what you want, assuming your version and useragents lists are aligned.

The equivalent of your for loop is the following list comprehension:

res = [link for link, ver in zip(useragents, version) if ver > 60]
like image 66
jpp Avatar answered Sep 29 '22 12:09

jpp