This question already has answers here:
Is there any built-in way to get the length of an iterable in python?
(10 answers)
What's the shortest way to count the number of items in a generator/iterator?
(7 answers)
Closed 4 years ago.
Is there anyway to see the len() of an itertools.Combination or other object, really, without materializing it to a list?
I can get the cardinality of combs or permutations with the factorials,... but I want something that generalizes.
Thanks
For any iterable it, you can do:
length = sum(1 for ignore in it)
That doesn't create a list, so the memory footprint is small. But for many kinds of iterables, it also consumes it (for example, if it is a generator, it's consumed and can't be restarted; if it is a list, it's not consumed). There is no generally "non-destructive" way to determine the length of an arbitrary iterable.
Also note that the code above will run "forever" if it delivers an unbounded sequence of objects.
No need to create a list. You can count the number of items in an iterable without storing the entire set:
sum(1 for _ in myIterable)
Yes,
def count_iterable(i):
return sum(1 for e in i)
Taken from: Is there any built-in way to get the length of an iterable in python?
Related
This question already has answers here:
Difference between reverse and [::-1]
(2 answers)
Time complexity of reversed() in Python 3
(1 answer)
Closed last month.
Python provides two ways to reverse a list:
List slicing notation
['a','b','c'][::-1] # ['c','b','a']
Built-in reversed() function
reversed(['a','b','c']) # ['c','b','a']
Are there any relevant differences in implementation/performance, or scenarios when one is preferred over the other?
The slicing operator constructs a new list in memory, which has implications on both memory and runtime.
reversed, on the other hand, returns an iterator which simply yields items one after another from the original list in reversed order. It does not allocate any additional memory.
So if all you're doing is iterating over the list in reverse and there's no need to construct a new (for example if you need to mutate it), then I'd say go for reversed.
This question already has answers here:
What are iterator, iterable, and iteration?
(16 answers)
Closed 2 years ago.
I came across certain built-in functions such as zip and map.
I tried printing these functions, they resulted as zip object at 0x1007a06c8 or <map object at 0x003AB2E0>.
I understand that these functions return iterators, but I can also use a for loop to run through strings/lists/dicts as iterators. Thus, how are zip and map different, and how I am able to show them? What are some other examples that I should be aware of?
Do something like:
list(zip(a,b))
Explanation:
The zip() function in Python 3 returns an iterator.
The purpose of this is to save memory by only generating the elements of the iterator as you need them, rather than putting it all into memory at once.
You can exhaust it once by doing list(zip(a,b)). So after that anytime you do list(zip(a,b)) would only result in empty list.
zip, map and also range are no collections like lists, strings, sets or dicts, because they are evaluated lazily. This means, that they do not explicitly contain all the values, but only generate the next value when asked to do that (e.g. in a loop or when unpacked in a list).
So lists and maps are iterable, because you can iterate over them, but maps are generators, while lists are containers.
You can unpack generators to a list with list(map(...)) (also works sets or tuples and others), or use the asterisk (*) to unpack them to individual arguments of a function (print(*map(...))).
This question already has answers here:
How can I make a dictionary (dict) from separate lists of keys and values?
(21 answers)
Closed 8 years ago.
With two lists of different sizes:
numbers=[1,2,3,4,5]
cities=['LA','NY','SF']
I need to get this:
result={1:'LA', 2:'NY', 3:'SF'}
I thought of doing it with:
result={number:cities[numbers.index(number)] for number in numbers if numbers.index(number)<len(cities)}
But this one-liner gets kind of long. I wonder if there is an alternative way of achieving the same goal.
EDITED LATER:
There were multiple suggestions made to use zip:
dict(zip(cities, numbers))
While it is a definitely a simpler syntax than list comprehension I've used I wonder which would be faster to execute?
Use zip, it will only zip upto the end of the shortest sequence
dict(zip(cities, numbers))
numbers=[1,2,3,4,5]
cities=['LA','NY','SF']
dict(zip(cities,numbers))
;)
I suspect it is duplicate though - search before you post
The easiest is probably dict(zip(numbers,cities))
zip will stop once any of the lists ends, which is what you want.
This question already has answers here:
How Big can a Python List Get?
(10 answers)
Closed 8 years ago.
So, I have this little bit of code here that I made for fun,
import itertools
list = []
for int in itertools.count():
list.append(int)
print list[int]
Now, all of my friends tell me this will stop working at some point. This led me to believe lists can only contain a finite amount of items. Is this true? If so, what is the limit?
Yes, there is a limit, sys.maxsize is the maximum number of entries a list can contain:
The largest positive integer supported by the platform’s Py_ssize_t type, and thus the maximum size lists, strings, dicts, and many other containers can have.
This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Finding the index of a list in a loop
Assume you have a list, where not just the values have meaning, the index has, too.
counts = [3,4,5,3,1]
Let's say that means "we have 3 objects of type zero, 4 objects of type 1 and so on".
You want to create a list of objects from that and give these objects both information details:
[CountObject(amount=a,type=???) for a in counts]
How would you do that?
Use the enumerate() function:
[CountObject(amount=a, type=i) for i, a in enumerate(counts)]
where i is then the index.
Something like:
[CountObject(amount=counts[a],type=a) for a in range(len(counts))]
would do what you want i guess .
beside enumerate() you can also try range(), use xrange() if you're on python 2.x:
[CountObject(amount=counts[i],type=i) for i in range(len(counts))]