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












14
















This question already has an answer here:




  • Nested list comprehension with two lists

    5 answers




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?










share|improve this question















marked as duplicate by coldspeed python
Users with the  python badge can single-handedly close python questions as duplicates and reopen them as needed.

StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Jan 29 at 18:24


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.























    14
















    This question already has an answer here:




    • Nested list comprehension with two lists

      5 answers




    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?










    share|improve this question















    marked as duplicate by coldspeed python
    Users with the  python badge can single-handedly close python questions as duplicates and reopen them as needed.

    StackExchange.ready(function() {
    if (StackExchange.options.isMobile) return;

    $('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
    var $hover = $(this).addClass('hover-bound'),
    $msg = $hover.siblings('.dupe-hammer-message');

    $hover.hover(
    function() {
    $hover.showInfoMessage('', {
    messageElement: $msg.clone().show(),
    transient: false,
    position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
    dismissable: false,
    relativeToBody: true
    });
    },
    function() {
    StackExchange.helpers.removeMessages();
    }
    );
    });
    });
    Jan 29 at 18:24


    This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.





















      14












      14








      14


      2







      This question already has an answer here:




      • Nested list comprehension with two lists

        5 answers




      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?










      share|improve this question

















      This question already has an answer here:




      • Nested list comprehension with two lists

        5 answers




      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?





      This question already has an answer here:




      • Nested list comprehension with two lists

        5 answers








      python list-comprehension






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jan 29 at 14:35









      gary

      3,85822548




      3,85822548










      asked Jan 29 at 12:29









      ViktorViktor

      352215




      352215




      marked as duplicate by coldspeed python
      Users with the  python badge can single-handedly close python questions as duplicates and reopen them as needed.

      StackExchange.ready(function() {
      if (StackExchange.options.isMobile) return;

      $('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
      var $hover = $(this).addClass('hover-bound'),
      $msg = $hover.siblings('.dupe-hammer-message');

      $hover.hover(
      function() {
      $hover.showInfoMessage('', {
      messageElement: $msg.clone().show(),
      transient: false,
      position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
      dismissable: false,
      relativeToBody: true
      });
      },
      function() {
      StackExchange.helpers.removeMessages();
      }
      );
      });
      });
      Jan 29 at 18:24


      This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.









      marked as duplicate by coldspeed python
      Users with the  python badge can single-handedly close python questions as duplicates and reopen them as needed.

      StackExchange.ready(function() {
      if (StackExchange.options.isMobile) return;

      $('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
      var $hover = $(this).addClass('hover-bound'),
      $msg = $hover.siblings('.dupe-hammer-message');

      $hover.hover(
      function() {
      $hover.showInfoMessage('', {
      messageElement: $msg.clone().show(),
      transient: false,
      position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
      dismissable: false,
      relativeToBody: true
      });
      },
      function() {
      StackExchange.helpers.removeMessages();
      }
      );
      });
      });
      Jan 29 at 18:24


      This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.


























          5 Answers
          5






          active

          oldest

          votes


















          25














          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]





          share|improve this answer































            8














            [link for (link, ver) in zip(useragents, version) if ver > 60]


            You still have to zip the two lists together.






            share|improve this answer































              5














              This



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


              is not the same as zip. It's not iterating through the two sequences in parallel. It's iterating through all combinations of those two sequences.



              It is as if you wrote:



              for ver in version:
              for link in useragents:
              if ver > 60:
              # append(link)


              So if both sequences had length 5, there would be 25 combinations (some of which are filtered out by the condition ver > 60).



              When you want to go through sequences in parallel, zip is the way to do it, even in a comprehension.



              [link for (link, ver) in zip(useragents, version) if ver > 60]





              share|improve this answer































                2














                Alternatively you can use the function compress() in combination with map(), where you check some condition:



                from itertools import compress

                filter_ = map(lambda x: x > 60, version)
                list(compress(useragents, filter_))


                Example:



                s = 'ABCDEFG'
                nums = range(len(s))

                filter_ = map(lambda x: x > 3, nums)
                print(list(compress(s, filter_)))
                # ['E', 'F', 'G']





                share|improve this answer

































                  0














                  Can't be sure on what's happening, without your data, but in general, "double" list comprehension is not the same as zip, but rather a double loop, i.e.



                  [a for b in bs for a in as]


                  is equivalent to



                  for b in bs:
                  for a in as:
                  lst.append(a)





                  share|improve this answer






























                    5 Answers
                    5






                    active

                    oldest

                    votes








                    5 Answers
                    5






                    active

                    oldest

                    votes









                    active

                    oldest

                    votes






                    active

                    oldest

                    votes









                    25














                    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]





                    share|improve this answer




























                      25














                      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]





                      share|improve this answer


























                        25












                        25








                        25







                        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]





                        share|improve this answer













                        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]






                        share|improve this answer












                        share|improve this answer



                        share|improve this answer










                        answered Jan 29 at 12:34









                        jppjpp

                        102k2165116




                        102k2165116

























                            8














                            [link for (link, ver) in zip(useragents, version) if ver > 60]


                            You still have to zip the two lists together.






                            share|improve this answer




























                              8














                              [link for (link, ver) in zip(useragents, version) if ver > 60]


                              You still have to zip the two lists together.






                              share|improve this answer


























                                8












                                8








                                8







                                [link for (link, ver) in zip(useragents, version) if ver > 60]


                                You still have to zip the two lists together.






                                share|improve this answer













                                [link for (link, ver) in zip(useragents, version) if ver > 60]


                                You still have to zip the two lists together.







                                share|improve this answer












                                share|improve this answer



                                share|improve this answer










                                answered Jan 29 at 12:33









                                shuebnershuebner

                                815




                                815























                                    5














                                    This



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


                                    is not the same as zip. It's not iterating through the two sequences in parallel. It's iterating through all combinations of those two sequences.



                                    It is as if you wrote:



                                    for ver in version:
                                    for link in useragents:
                                    if ver > 60:
                                    # append(link)


                                    So if both sequences had length 5, there would be 25 combinations (some of which are filtered out by the condition ver > 60).



                                    When you want to go through sequences in parallel, zip is the way to do it, even in a comprehension.



                                    [link for (link, ver) in zip(useragents, version) if ver > 60]





                                    share|improve this answer




























                                      5














                                      This



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


                                      is not the same as zip. It's not iterating through the two sequences in parallel. It's iterating through all combinations of those two sequences.



                                      It is as if you wrote:



                                      for ver in version:
                                      for link in useragents:
                                      if ver > 60:
                                      # append(link)


                                      So if both sequences had length 5, there would be 25 combinations (some of which are filtered out by the condition ver > 60).



                                      When you want to go through sequences in parallel, zip is the way to do it, even in a comprehension.



                                      [link for (link, ver) in zip(useragents, version) if ver > 60]





                                      share|improve this answer


























                                        5












                                        5








                                        5







                                        This



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


                                        is not the same as zip. It's not iterating through the two sequences in parallel. It's iterating through all combinations of those two sequences.



                                        It is as if you wrote:



                                        for ver in version:
                                        for link in useragents:
                                        if ver > 60:
                                        # append(link)


                                        So if both sequences had length 5, there would be 25 combinations (some of which are filtered out by the condition ver > 60).



                                        When you want to go through sequences in parallel, zip is the way to do it, even in a comprehension.



                                        [link for (link, ver) in zip(useragents, version) if ver > 60]





                                        share|improve this answer













                                        This



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


                                        is not the same as zip. It's not iterating through the two sequences in parallel. It's iterating through all combinations of those two sequences.



                                        It is as if you wrote:



                                        for ver in version:
                                        for link in useragents:
                                        if ver > 60:
                                        # append(link)


                                        So if both sequences had length 5, there would be 25 combinations (some of which are filtered out by the condition ver > 60).



                                        When you want to go through sequences in parallel, zip is the way to do it, even in a comprehension.



                                        [link for (link, ver) in zip(useragents, version) if ver > 60]






                                        share|improve this answer












                                        share|improve this answer



                                        share|improve this answer










                                        answered Jan 29 at 12:36









                                        khelwoodkhelwood

                                        32.1k74465




                                        32.1k74465























                                            2














                                            Alternatively you can use the function compress() in combination with map(), where you check some condition:



                                            from itertools import compress

                                            filter_ = map(lambda x: x > 60, version)
                                            list(compress(useragents, filter_))


                                            Example:



                                            s = 'ABCDEFG'
                                            nums = range(len(s))

                                            filter_ = map(lambda x: x > 3, nums)
                                            print(list(compress(s, filter_)))
                                            # ['E', 'F', 'G']





                                            share|improve this answer






























                                              2














                                              Alternatively you can use the function compress() in combination with map(), where you check some condition:



                                              from itertools import compress

                                              filter_ = map(lambda x: x > 60, version)
                                              list(compress(useragents, filter_))


                                              Example:



                                              s = 'ABCDEFG'
                                              nums = range(len(s))

                                              filter_ = map(lambda x: x > 3, nums)
                                              print(list(compress(s, filter_)))
                                              # ['E', 'F', 'G']





                                              share|improve this answer




























                                                2












                                                2








                                                2







                                                Alternatively you can use the function compress() in combination with map(), where you check some condition:



                                                from itertools import compress

                                                filter_ = map(lambda x: x > 60, version)
                                                list(compress(useragents, filter_))


                                                Example:



                                                s = 'ABCDEFG'
                                                nums = range(len(s))

                                                filter_ = map(lambda x: x > 3, nums)
                                                print(list(compress(s, filter_)))
                                                # ['E', 'F', 'G']





                                                share|improve this answer















                                                Alternatively you can use the function compress() in combination with map(), where you check some condition:



                                                from itertools import compress

                                                filter_ = map(lambda x: x > 60, version)
                                                list(compress(useragents, filter_))


                                                Example:



                                                s = 'ABCDEFG'
                                                nums = range(len(s))

                                                filter_ = map(lambda x: x > 3, nums)
                                                print(list(compress(s, filter_)))
                                                # ['E', 'F', 'G']






                                                share|improve this answer














                                                share|improve this answer



                                                share|improve this answer








                                                edited Jan 29 at 21:10

























                                                answered Jan 29 at 12:41









                                                Mykola ZotkoMykola Zotko

                                                1,865518




                                                1,865518























                                                    0














                                                    Can't be sure on what's happening, without your data, but in general, "double" list comprehension is not the same as zip, but rather a double loop, i.e.



                                                    [a for b in bs for a in as]


                                                    is equivalent to



                                                    for b in bs:
                                                    for a in as:
                                                    lst.append(a)





                                                    share|improve this answer




























                                                      0














                                                      Can't be sure on what's happening, without your data, but in general, "double" list comprehension is not the same as zip, but rather a double loop, i.e.



                                                      [a for b in bs for a in as]


                                                      is equivalent to



                                                      for b in bs:
                                                      for a in as:
                                                      lst.append(a)





                                                      share|improve this answer


























                                                        0












                                                        0








                                                        0







                                                        Can't be sure on what's happening, without your data, but in general, "double" list comprehension is not the same as zip, but rather a double loop, i.e.



                                                        [a for b in bs for a in as]


                                                        is equivalent to



                                                        for b in bs:
                                                        for a in as:
                                                        lst.append(a)





                                                        share|improve this answer













                                                        Can't be sure on what's happening, without your data, but in general, "double" list comprehension is not the same as zip, but rather a double loop, i.e.



                                                        [a for b in bs for a in as]


                                                        is equivalent to



                                                        for b in bs:
                                                        for a in as:
                                                        lst.append(a)






                                                        share|improve this answer












                                                        share|improve this answer



                                                        share|improve this answer










                                                        answered Jan 29 at 12:35









                                                        SlamSlam

                                                        5,53712435




                                                        5,53712435















                                                            Popular posts from this blog

                                                            Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

                                                            Does disintegrating a polymorphed enemy still kill it after the 2018 errata?

                                                            A Topological Invariant for $pi_3(U(n))$