Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performing len on list of a zip object clears zip [duplicate]

I am seeing a strange behavior when working with the zip() function. When I perform the following operation len(list(z)) where z is a zip object, the result is 0 (which seems wrong to me), and the action seems to clear out the zip object. Can someone please help me understand what is going on.

# python3
Python 3.2.3 (default, Sep 30 2012, 16:41:36) 
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> w = [11, 22, 33, 44, 55, 66]
>>> x = [1, 2, 3, 4]
>>> y = ['a', 'b', 'c']
>>> z = zip(x, y, w)
>>> z
<zip object at 0x7f854f613cb0>
>>> list(z)
[(1, 'a', 11), (2, 'b', 22), (3, 'c', 33)]
>>> len(list(z))
0
>>> list(z)
[]
>>> z
<zip object at 0x7f854f613cb0>
>>> 

Thank you, Ahmed.

like image 904
Ahmed A Avatar asked Jan 31 '13 23:01

Ahmed A


People also ask

Why do you use the zip () method in python?

zip() in Python Python zip() method takes iterable or containers and returns a single iterator object, having mapped values from all the containers. It is used to map the similar index of multiple containers so that they can be used just using a single entity.

What does zip (* List do in Python?

Python's zip() function is defined as zip(*iterables) . The function takes in iterables as arguments and returns an iterator. This iterator generates a series of tuples containing elements from each iterable. zip() can accept any type of iterable, such as files, lists, tuples, dictionaries, sets, and so on.

What happens if you zip two lists of different lengths?

Answer. The zip() function will only iterate over the smallest list passed. If given lists of different lengths, the resulting combination will only be as long as the smallest list passed.

What is the role of the * operator within the zip () function?

Basically, it passes the contents of the lists as arguments.


2 Answers

In Python 3 zip is a generator. The generator is being exhausted when you do list(z). You can create a list from the values returned by the generator and operate on that.

l = list(z)
len(l)
# -> 3
l
# -> [(1, 'a', 11), (2, 'b', 22), (3, 'c', 33)]

Generators are a good thing. They allow us to write memory-efficient code in nearly the same way we would write code that deals with lists. To use an example from the linked wiki:

def double(L):
    return [x*2 for x in L]

Could be rewritten as a generator to avoid creating another list in memory:

def double(L):
    for x in L:
        yield x*2
like image 161
mechanical_meat Avatar answered Oct 03 '22 08:10

mechanical_meat


To complete the previous answer, there is a Python library called cardinality for getting the size of iterables.

http://cardinality.readthedocs.io/en/latest/

like image 44
Eskapp Avatar answered Oct 03 '22 10:10

Eskapp