Generator Expressions vs. List Comprehension

前端 未结 9 1778
梦如初夏
梦如初夏 2020-11-21 06:56

When should you use generator expressions and when should you use list comprehensions in Python?

# Generator expression
(x*2 for x in range(256))

# List com         


        
相关标签:
9条回答
  • 2020-11-21 07:07

    Python 3.7:

    List comprehensions are faster.

    Generators are more memory efficient.

    As all others have said, if you're looking to scale infinite data, you'll need a generator eventually. For relatively static small and medium-sized jobs where speed is necessary, a list comprehension is best.

    0 讨论(0)
  • 2020-11-21 07:10

    Sometimes you can get away with the tee function from itertools, it returns multiple iterators for the same generator that can be used independently.

    0 讨论(0)
  • 2020-11-21 07:11

    John's answer is good (that list comprehensions are better when you want to iterate over something multiple times). However, it's also worth noting that you should use a list if you want to use any of the list methods. For example, the following code won't work:

    def gen():
        return (something for something in get_some_stuff())
    
    print gen()[:2]     # generators don't support indexing or slicing
    print [5,6] + gen() # generators can't be added to lists
    

    Basically, use a generator expression if all you're doing is iterating once. If you want to store and use the generated results, then you're probably better off with a list comprehension.

    Since performance is the most common reason to choose one over the other, my advice is to not worry about it and just pick one; if you find that your program is running too slowly, then and only then should you go back and worry about tuning your code.

    0 讨论(0)
  • 2020-11-21 07:12

    When creating a generator from a mutable object (like a list) be aware that the generator will get evaluated on the state of the list at time of using the generator, not at time of the creation of the generator:

    >>> mylist = ["a", "b", "c"]
    >>> gen = (elem + "1" for elem in mylist)
    >>> mylist.clear()
    >>> for x in gen: print (x)
    # nothing
    

    If there is any chance of your list getting modified (or a mutable object inside that list) but you need the state at creation of the generator you need to use a list comprehension instead.

    0 讨论(0)
  • 2020-11-21 07:14

    The benefit of a generator expression is that it uses less memory since it doesn't build the whole list at once. Generator expressions are best used when the list is an intermediary, such as summing the results, or creating a dict out of the results.

    For example:

    sum(x*2 for x in xrange(256))
    
    dict( (k, some_func(k)) for k in some_list_of_keys )
    

    The advantage there is that the list isn't completely generated, and thus little memory is used (and should also be faster)

    You should, though, use list comprehensions when the desired final product is a list. You are not going to save any memeory using generator expressions, since you want the generated list. You also get the benefit of being able to use any of the list functions like sorted or reversed.

    For example:

    reversed( [x*2 for x in xrange(256)] )
    
    0 讨论(0)
  • 2020-11-21 07:15

    Iterating over the generator expression or the list comprehension will do the same thing. However, the list comprehension will create the entire list in memory first while the generator expression will create the items on the fly, so you are able to use it for very large (and also infinite!) sequences.

    0 讨论(0)
提交回复
热议问题