Code:
nums = {1,2,3,4,5,6} nums = {0,1,2,3} & nums print(nums) nums=filter(lambda x: x > 1, nums) print(nums) print(len(list(nums))) print(len(list(nums)))
this is the output:
{1, 2, 3} <filter object at 0x000001FDFECD2850> 2 0
Why printing(len(list(nums)) will output different result?
Advertisement
Answer
Short answer: Because the filter function returns an iterator, and the first call list function consumes all the elements of the iterator, so the second time you call the list function on the same iterator you will get an empty list.
Deep insight:
The term “consume” is an informal term that refers to the way iterators work in Python. An “iterator” is a single object responsible for creating a sequence of elements.
When a caller requests the “next” element from an iterator, the iterator provides the next element and then changes its state so that it is ready to produce the next element.
The built-in function list, if iterable is passed as a parameter, it “consumes” the iterable object and it creates a list consisting of iterable’s items.
Example:
If I have an iterator with the numbers 2 to 6, the first time I call it “next” I will get 2 in return and the elements [3,4,5,6] remain in the iterator (TEST 1). The next time, I will get 3 and [4,5,6] will remain in the iterator (TEST 2). The next time, I will get 4 and in the iterator they will remain [5,6] (TEST 3). And so on until the iterator is empty, and the “next” operation on the iterator raises the StopIteration exception (TEST 4).
Tests:
print("n** TEST 1 **") nums = [1,2,3,4,5,6] iter_nums = filter(lambda x: x > 1, nums) print("Item Consumed: ", next(iter_nums)) print("Item remained in the iterator:", list(iter_nums)) # ** TEST 1 ** # Item Consumed: 2 # Item remained in the iterator: [3, 4, 5, 6] print("n**TEST 2 **") iter_nums = filter(lambda x: x > 1, nums) print("Item Consumed: ", next(iter_nums)) print("Item Consumed: ", next(iter_nums)) print("Item remained in the iterator:", list(iter_nums)) # ** TEST 2 ** # Item Consumed: 2 # Item Consumed: 3 # Item remained in the iterator: [4, 5, 6] print("n**TEST 3 **") iter_nums = filter(lambda x: x > 1, nums) print("Item Consumed: ", next(iter_nums)) print("Item Consumed: ", next(iter_nums)) print("Item Consumed: ", next(iter_nums)) print("Item remained in the iterator:", list(iter_nums)) # ** TEST 3 ** # Item Consumed: 2 # Item Consumed: 3 # Item Consumed: 4 # Item remained in the iterator: [5, 6] print("n**TEST 4 **") iter_nums = filter(lambda x: x > 1, nums) print("Item Consumed: ", next(iter_nums)) print("Item Consumed: ", next(iter_nums)) print("Item Consumed: ", next(iter_nums)) print("Item Consumed: ", next(iter_nums)) print("Item Consumed: ", next(iter_nums)) print("Item Consumed: ", next(iter_nums)) print("Item remained in the iterator:", list(iter_nums)) # ** TEST 3 ** # Item Consumed: 2 # Item Consumed: 3 # Item Consumed: 4 # Item Consumed: 5 # Item Consumed: 6 # ------------ StopIteration Traceback (most recent call last)