Yes, but not if we use a list comprehension, which always returns a list. This means that even if the resulting list would be extremely long, we won’t use up tons of memory by returning it all at once. Now, there’s one thing left to do here to make it a bit closer to the real “zip”: As I mentioned above, Python 2’s “zip” returns a list, but Python 3’s “zip” returns an iterator object. So if the shortest sequence is ‘abc’, we’ll end up returning range(3), giving us indexes 0, 1, and 2 - perfect for our needs. The sequences are sorted by length, and then the first (shortest) sequence is passed to “len”, which calculates the length and then returns the result of running “range”. Now, our function takes *args, meaning that it can take any number of sequences. This is getting a wee bit complex for a single list comprehension, so I’m going to break off part of the second line into a function, just to clean things up a tiny bit: > def shortest_sequence_range(*args): Putting this all together in our comprehension, we get: >, t)įor i in range(len(sorted((s,t), key=len)))] (If all sequences are the same size, then we don’t care which one we get back.) This means that the element at index 0 is guaranteed not to be longer than any other sequence. Because we pass the builtin “len” function to the “key” parameter, “sorted” will return if s is shorter, and if t is shorter. Given these inputs, we will get a list back from “sorted”. In the above code, I create a new tuple, (s,t), and pass that as the first parameter to “sorted”. We can do this via the “sorted” builtin function, telling it to sort the sequences by length, from shortest to longest. What that means is not just running range(len(s)), but running range(len(x)), where x is the shorter sequence. To be honest, this works pretty well! But there are a few ways in which we could improve it.įirst of all, it would be nice to make our comprehension-based “zip” alternative handle inputs of different sizes. One way to do this is to say:, t) # produce a two-element tupleįor i in range(len(s))] # from index 0 to len(s) - 1 So last week, when a student of mine asked if we could implement “zip” using list comprehensions, I couldn’t resist.įirst, let’s assume that we have our two equal-length sequences from above, s (a string) and t (a tuple). Now, if there’s something I like even more than “zip”, it’s list comprehensions. (If you want zip to return one tuple for every element of the longer iterable, then use “ izip_longest” from the “ itertools” package.) Simply put, the shortest one wins: > s = 'abc' Whenever I mention “zip” in my programming classes, someone inevitably asks what happens if one argument is shorter than the other. In this way, we’re able to quickly and easily product a dict from two parallel sequences. I often use “zip” to turn parallel sequences into dictionaries. (You can also invoke zip with a single iterable, thus ending up with a bunch of one-element tuples, but that seems a bit weird to me.) You can use zip with more than one iterable, as well: > s = 'abc' In Python 3, you get a “zip object” back.) The tuple at index 0 contains s and t. Before I describe what “zip” does, let me first show you an example: > s = 'abc'Īs you can see, the result of “zip” is a sequence of tuples. I’m not sure just what it is about zip that I enjoy, but I have often found it to be quite useful. Introduction to machine learning in Python.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |