zip関数の目的は何ですか(PythonまたはC#4.0の場合のように)?




c# python 速度 (6)

zipは、複数の反復可能オブジェクトを同時に反復処理する場合に便利です。これは、Pythonではかなり一般的なシナリオです。

私にとってzipが便利になっている現実的なシナリオの1つは、M x Nの配列があり、行ではなく列を調べたい場合です。 例えば:

>>> five_by_two = ((0, 1), (1, 2), (2, 3), (3, 4), (4, 5))
>>> two_by_five = tuple(zip(*five_by_two))
>>> two_by_five
((0, 1, 2, 3, 4), (1, 2, 3, 4, 5))

誰かがC#でPythonのzipをどうやってやるのかと尋ねましたか? ...

...これは私に尋ねるように導きます、zipは何が良いのですか? どのようなシナリオでこれが必要ですか? それは本当にとても基本的なことなので、私はこれを基本クラスのライブラリで必要としますか?


ユースケース:

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

zipなしでこれを試してみてください...


これは、バージョン番号を比較するためのPythonクラスで、効果的にzip()を使用した場合です。

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

私は、 zip()all()およびany()と組み合わせると、比較演算子の実装が特に明確かつエレガントになると思います。 確かに、それはzip()なしで行われたかもしれませんが、それから同じことが実質的にどんな言語機能についても言えるでしょう。


これがzipの一般的な使用例です。

x = [1,2,3,4,5]
y = [6,7,8,9,0]

for a,b in zip(x,y):
    print a, b

どれが出力されます:

1 6
2 7
3 8
4 9
5 0

これを使用すると、シーケンスを順番に、または入れ子にするのではなく、並行して処理できます。 そこには...非常に多くの用途があり、それらは現在私を免れています。


Zipエクステンション方式で回答したというごく最近の人が、ここで実際に質問をしたので、 一部の人にとって明らかに重要です。 ;)

実際、それは数学的アルゴリズムにとって非常に重要な操作です - 行列、曲線当てはめ、補間、パターン認識、そのようなこと。 デジタル信号処理のように、複数の信号を組み合わせたり、それらに線形変換を適用したりすることが多いエンジニアリングアプリケーションでも非常に重要です。どちらもサンプルインデックスに基づいているため、zipで圧縮します。 特にシーケンスの要素数が同じで順序が同じであることが事前にわかっている場合は、2つのシーケンスをジップすることは、キーに基づいて並べ替えて結合するよりもはるかに速くなります。

私の現在の雇用のためにここで厳密な詳細に入ることはできませんが、一般的に言えば、これは遠隔測定データにとっても価値があります - 産業的、科学的、その種のこと。 多くの場合、何百または何千ものポイント(パラレルソース)からのデータの時系列があります。また、時間をかけずに、 水平方向に 、デバイスごとに集計する必要があります。 最後に、別の時系列が必要ですが、合計または平均、あるいはすべての個々の点のその他の集計が必要です。

SQL Serverでの単純なsort / group / joinのように聞こえるかもしれませんが、この方法で効率的に実行するのは実際には本当に困難です。 一つには、タイムスタンプは正確に一致しないかもしれませんが、数ミリ秒の違いを気にしないので、代わりに代理キー/行番号とグループを生成しなければならなくなります - そしてもちろん、代理行番号あなたがすでに持っていたタイムインデックス以上の何ものでもありません。 ジッピングは単純、高速、そして無限並列化が可能です。

私がそれを基本的なものと呼ぶかどうかはわかりませんが、それは重要です。 私はReverseメソッドもあまり頻繁には使用しませんが、その必要性があるときにまれに自分でそれを記述し続ける必要がないのと同じ理由で、私は嬉しく思います。

今ではあまり役に立たないと思われる理由の1つは、.NET / C#3.5にタプルがないことです。 C#4 はタプルを持っています 、そして、タプルを使って作業しているとき、順序付けが厳密に強制されているので、本当にジッピング基本的な操作です。





zip