For example I have the following code:
d = [l for l in open('a.txt', 'r')]
After d
is created, will the stream opened in the list comprehension get closed automatically ?
A Python list comprehension consists of brackets containing the expression, which is executed for each element along with the for loop to iterate over each element in the Python list. Python List comprehension provides a much more short syntax for creating a new list based on the values of an existing list.
Yes, the list comprehension preserves the order of the original iterable (if there is one). If the original iterable is ordered (list, tuple, file, etc.), that's the order you'll get in the result. If your iterable is unordered (set, dict, etc.), there are no guarantees about the order of the items.
List comprehensions are a way of achieving Pythonic one-liners with iterables (lists). One-line definitions: List = a Python object which can be iterated over (an iterable). Iterated over = going through something one-by-one.
Every list comprehension in Python includes three elements: expression is the member itself, a call to a method, or any other valid expression that returns a value. In the example above, the expression i * i is the square of the member value. member is the object or value in the list or iterable.
"Maybe".
In cPython, which uses refcounting, the file will be closed as soon as the list comprehension finishes (and all references to the file
object are lost).
But the Python standard does not require that it be closed. For example, the file will not be closed immediately in jython, which uses the JVM garbage collector.
The "preferred" method of ensuring that resources are correctly closed is the with
statement:
with open(…) as f:
d = [l for l in f]
This will guarantee that the file get closed.
And, as @astynax points out, you might be able to use d = f.readlines()
here, as it would have the same semantics as the list comprehension.
To prove this to yourself (in cpython):
>>> class Foo(object): ... def __del__(self): ... print "in __del__" ... def __iter__(self): ... return iter([1, 2, 3, 4]) ... >>> [ x for x in Foo() ] in __del__ [1, 2, 3, 4]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With