C#プログラマからみたPython 内包表記編

内包表記

C#でいうところのLINQに近いイメージ。 Pythonではリストの初期化(宣言)時にブロックを利用せずにインラインで記載することが出来る。

#内包表記。
sp2 = [x ** 2 for x in range(1,10)]
print(sp2)
#内包表記を利用しない書き方
sp = []
for x in range(1,10):
    sp.append(x ** 2)
print(sp)

C#だとこんな感じ。

//C#
var ten = Enumerable.Range(1, 9);
var sp2 = from n in ten select n * n;

ただし、PythonにはC#のクエリ式にあるような強力な構文(orderとか)はないっぽい。

リスト内包表記はリストを返却する式のため、式を記述できる場所にはどこでも記述することができる。したがって以下のようなことも可能。

sp3 = [(x, [y for y in range(1, x) if x % y == 0]) for x in range(1, 11)]

なお、これは数と公約数を調べるリスト。 この時点で脳がこんがらがってくるし、コメントも打ちづらいので過剰に利用するのは禁物かな。 LINQなどでも一緒だけど。

ちなみにPython3からはディクショナリとsetに対しても内包表記が追加されている。 多少構文が異なる程度で、考え方はリストの内包表記と同様。

イテレータ(ジェネレータ関数)

C#イテレータPythonイテレータ(ジェネレータ)はよく似ている。

イテレータはそもそも”順番をともなった複数の要素を抽象的に扱うための仕組み”を指すことだと考えており、Pythonの場合はイテレータとジェネレータという形に分けられている。

対してC#の場合は、イテレータブロックというような表現がされており、イテレータが仕組みではなく構文のような扱いになっていることから、Pythonイテレータ(ジェネレータ)という書き方にした次第。。。

#python
def get_primes(x = 2):
    while True:
        for i in range(2,x):
            if x % i == 0:
                break
        else:
            yield x
        x += 1

C#のコードは面倒なので割愛( ー`дー´)
どのみち構文は全く似とらんし。

ただし、役割としては似ていて、どちらもフィボナッチ数列素数やらを求めるようなものや、予めループの回数が決まっていないようなものに対して強力。

ジェネレータ式

Python3からはジェネレータ式も導入されており、リスト内包表記と同じような書き方で、ジェネレーターを定義することが可能。

gen = (ord(s) for s in "python")