What is the purpose of a zip function (as in Python or C# 4.0)?

后端 未结 7 2193
北荒
北荒 2020-12-29 09:27

Someone asked How to do Python’s zip in C#?...

...which leads me to ask, what good is zip? In what scenarios do I need this? Is it really so foundational that I n

相关标签:
7条回答
  • 2020-12-29 09:44

    It's handy in different places. My favorite, from http://norvig.com/python-iaq.html, is transposing a matrix:

    >>> x = [ [1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15]]
    >>> zip(*x)
    [(1, 6, 11), (2, 7, 12), (3, 8, 13), (4, 9, 14), (5, 10, 15)]
    
    0 讨论(0)
  • 2020-12-29 09:45

    It allows you to process sequences in parallel instead of sequentially or nested. There's... so many uses for it that they currently escape me.

    0 讨论(0)
  • 2020-12-29 09:48

    Here's a case where I used zip() to useful effect, in a Python class for comparing version numbers:

    class Version(object):
    
        # ... snip ...
    
        def get_tuple(self):
            return (self.major, self.minor, self.revision)
    
        def compare(self, other):
            def comp(a, b):
                if a == '*' or b == '*':
                    return 0
                elif a == b:
                    return 0
                elif a < b:
                    return -1
                else:
                    return 1
            return tuple(comp(a, b) for a, b in zip(self.get_tuple(), Version(other).get_tuple()))
    
        def is_compatible(self, other):
            tup = self.compare(other)
            return (tup[0] == 0 and tup[1] == 0)
    
        def __eq__(self, other):
            return all(x == 0 for x in self.compare(other))
    
        def __ne__(self, other):
            return any(x != 0 for x in self.compare(other))
    
        def __lt__(self, other):
            for x in self.compare(other):
                if x < 0:
                    return True
                elif x > 0:
                    return False
            return False
    
        def __gt__(self, other):
            for x in self.compare(other):
                if x > 0:
                    return True
                elif x < 0:
                    return False
            return False
    

    I think zip(), coupled with all() and any(), makes the comparison operator implementations particularly clear and elegant. Sure, it could have been done without zip(), but then the same could be said about practically any language feature.

    0 讨论(0)
  • 2020-12-29 09:51

    Someone actually asked a question here fairly recently that I answered with the Zip extension method, so it's obviously important for some people. ;)

    Actually, it is a fairly important operation for mathematical algorithms - matrices, curve fitting, interpolation, pattern recognition, that sort of thing. Also very important in engineering applications like digital signal processing where much of what you do is combine multiple signals or apply linear transforms to them - both are based on the sample index, hence, zip it. Zipping two sequences is far, far faster than sorting and joining them based on some key, especially when you know in advance that the sequences have the same number of elements and are in the same order.

    I can't get into tight specifics here on account of my current employment, but speaking generally, this is also valuable for telemetry data - industrial, scientific, that sort of thing. Often you'll have time sequences of data coming from hundreds or thousands of points - parallel sources - and you need to aggregate, but horizontally, over devices, not over time. At the end, you want another time sequence, but with the sum or average or some other aggregate of all the individual points.

    It may sound like a simple sort/group/join in SQL Server (for example) but it's actually really hard to do efficiently this way. For one thing, the timestamps may not match exactly, but you don't care about differences of a few milliseconds, so you end up having to generate a surrogate key/row number and group on that - and of course, the surrogate row number is nothing more than the time index which you already had. Zipping is simple, fast, and infinitely parallelizable.

    I don't know if I'd call it foundational, but it it is important. I don't use the Reverse method very often either, but by the same token I'm glad I don't have to keep writing it myself on those rare occasions when I do find a need for it.

    One of the reasons it might not seem that useful to you now is that .NET/C# 3.5 does not have tuples. C# 4 does have tuples, and when you're working with tuples, zipping really is a fundamental operation because ordering is strictly enforced.

    0 讨论(0)
  • 2020-12-29 09:51

    A use case:

    >>> fields = ["id", "name", "location"]
    >>> values = ["13", "bill", "redmond"]
    >>> dict(zip(fields, values))
    {'location': 'redmond', 'id': '13', 'name': 'bill'}
    

    Try doing this without zip...

    0 讨论(0)
  • 2020-12-29 09:54

    Here's a common use case for zip:

    x = [1,2,3,4,5]
    y = [6,7,8,9,0]
    
    for a,b in zip(x,y):
        print a, b
    

    Which would output:

    1 6
    2 7
    3 8
    4 9
    5 0
    
    0 讨论(0)
提交回复
热议问题