Python Essentials ***************************************** `Python_Essentials `_ Data Type ======================== `Data Type `_ では,Pythonでよく使われるデータの種類について学びます. Primitive Data Types ---------------------- Bool Type ----------------- 最も基本的なデータタイプは, Bool Typeです. これは,変数自体に ``True`` や ``False`` が入ります. :: >>> x = True という感じです. また,命題についても,``True`` or ``False`` に変換されて変数に入ります. :: >>> y = (100 < 10) >>> y False Data typeの確認方法 ------------------------------------------- プログラムを書いていて,ある変数がどのようなデータタイプなのか, わからなくなることがあります.これ以降にも,様々なデータタイプが出てきますが,先にデータタイプの確認方法を学びましょう. ある変数 ``x`` がどのようなデータタイプかを調べるためには組込み関数 ``type()`` を使います. :: >>> type(x) >>> bool bool Typeの性質 ------------------------------------------------------------------------ ``bool`` Typeの変数には ``True`` もしくは ``False`` が割り当てられますが, ``True`` と ``False`` にはそれぞれ, ``1`` と ``0`` という数字も割り当てられています :: >>> x, y = True, False >>> x + y 1 ListとBool --------------------------------------------- この,Bool TypeはListの要素にもなります. Listとは ------------------- Listは様々なオブジェクトを格納できる列のことです. Listには,値や文字なども入れることができます.例えば, :: >>> bools = [True, True, False, True] という感じです.先ほどの, ``True`` や ``False`` に ``1`` と ``0`` が割り当てられることを考えると, :: >>> sum(bools) 3 となります.この ``sum()`` のような命令のことを関数と呼びます. 特に,この ``sum()`` は組み込み関数とよばれ,pythonにもともと入っています. ほかの組み込み関数については,公式の組み込み関数_ を参照してください. そのほかのデータータイプ ----------------------------------------------------- PythonにはBool Type以外にのデータタイプも存在します. 例えば数字の, ``int`` と ``float`` の2つの種類のデータタイプがあります. :: >>> a, b = 1, 2 >>> type(a) int ``int`` がinterger Typeであり, :: >>> c, d = 2.5, 10.0 >>> type(c) float となります.この ``int`` と ``float`` については後に詳しく説明します. 注意 ---------------- この,integerに関連する問題を一つ見てみましょう. Python 2x では,2つのinteger(整数)同士の割り算では,integerの部分だけを返します. n:: >>> 1/2 0 ただし, ``integer`` と ``float`` や, ``float`` と ``float`` 同士の割り算では,少数以下も返されます. :: >>> 1.0/2.0 0.5 ですし, :: >>> 1.0/2 0.5 となります. このような問題はPython 3xでは発生しません.しかし,この教科書はPyhton 2xを用いるので,読者はこのような問題に留意する必要があるでしょう. complex Type -------------- 複素数も,PythonにおけるPrimitiveなデータタイプの一つです. Pythonでは,Complex Type と呼ばれます. Pythonで複素数を表現するには,組み込み関数の ``complex()`` を使います. ``complex(実部,虚部)`` のように指定します.また,Pythonでは複素数は ``j`` で表現されます. :: >>> x = complex(1, 2) >>> y = complex(2, 1) とすれば, :: >>> x*y 5j となります. Containers ----------------- Pythonには様々なコンテナが存在します. コンテナは,データーを集めておくために使われます. 例えば,先に説明した, ``list`` は組み込みコンテナといって,Pythonにもともと備わっています. listと同じような,組み込みコンテナとして ``tuple`` (トゥープル,タプル)があります. この, ``tuple`` と ``list`` の大きな違いの一つに, ``tupule`` が ``immutable`` であることが挙げられます. ``tuple`` が ``immutable`` とは, ``tuple`` の値が変更できないことを意味します. 一方で, ``list`` は ``mutable`` なので,値を変更することができます. 以下に例を示します,まず ``list`` は ``mutable`` すなわち持っている変数の数が増えたり,減ったり変わったりします. :: >>> x = [1, 2] という ``list`` を考え,この1行目の,1を変化させてみましょう. ところで,この行番号ですが,pythonでは,0から数えます. ``x[0]`` というようにすると, ``list`` であるxの0行目を指定できます.これを変更するには, :: >>> x[0]=10 というようにします.確認すると, :: >>> x [10, 2] というように,変更されていることがわかります. このように, ``list`` は ``mutabl`` です.しかし,一方で, ``tupule`` は ``immutable`` です. :: >>> X = (1, 2) X[0] = 10 --------------------------------------------------------------------------- TypeError Traceback (most recent call last) in () ----> 1 X[0] = 10 TypeError: 'tuple' object does not support item assignment となってしまいます もう少し,mutable とimmutableの話をしよう ----------------------------------------------------------------- ``mutable`` な ``list`` にも, ``immutable`` なリストにも, ``unpacke`` という操作を施すことができます. ``unpacked`` では,それぞれの行を指定した変数に当てはめることができます. :: integers = (10, 20, 30) x, y, z = integers とすると :: >>> x 10 >>> y 20 >>> z 30 というように割り当てられます. また,slice notetion という操作も, ``mutable`` , ``immutable`` のどちらにも施すことができます. 例えば, :: >>> a = [2, 4 , 6, 8] という,listの1行目から,最後の行までを抜き出したいときは, :: >>> a[1:] [4, 6, 8] と指定します. また,ある行から,ある行までを抜き出したいとき,例えば,1-2行目を抜き出したいとき, :: >>> a[1:3] [4, 6] というような指定の仕方をします. ``list[抜き出しを開始する行番号:抜き出しを終わる行番号+1]`` という感じです. また, :: >>> a[-2:] [6, 8] のように,最後の2行を抜き出すことができます. 以上の一連の操作は,文字列に対しても行えて, :: >>> s = 'kobe univ.' >>> s[-5:] 'univ.' と抜き出せることができます. このような,最後の数行を抜き出すという操作は,全体を確認するには長すぎるデータの内容を確認するときに,有効な場合があります. Sets と Dictionaries ------------------------------------- 先に, ``list`` と ``tupule`` という二種類の ``container`` を紹介しました. 次に, ``set`` と ``dictionary`` という2つの ``container`` について説明します. まず, ``dictionary`` は, ``list`` と似ていますが,要素がkeyと言われる変数とヒモ付されている点が異なります.:: d = {'name': 'Frodo', 'age' : 33} ここでは, ``'name'`` と ``'age'`` がkeyになっています. こうすることで,作った ``dictionary`` に対して,keyを指定することで,ヒモ付けされた情報を抜き出すことができます. :: >>> d['age'] 33 次に, ``set`` というコンテナについて説明します. ``set`` はその名の通り, 集合の ``container`` です. :: >>> s1 = {'a', 'b'} 当然, ``type(s1)`` は :: >>> type(s1) set となります. 別の, ``s2`` という ``set`` を考えてみましょう. :: >>> s2 = {'b', 'c'} ``set`` に対して,行える演算の一つに, ``issubset()`` があります. ``s1. issubset(s2)`` としたとき, ``s1`` が ``s2`` の部分集合の場合,Trueを返し,そうでないとき,Falseと返します. :: >>> s1. issubset(s2) False 他にも, ``issubset()`` は ``set`` 同士の共通部分を返します. :: >>> s1. intersection(s2) {'b'} 同じような,演算として,2つの集合の間の異なる要素を返す, ``difference()`` があります. :: >>> s1. difference(s2) {'a'} また, ``set`` は重複する要素を持ちません. :: >>> s3 = {'b', 'c', 'c', 'c'} としても, :: >>> s3 {'b', 'c'} となります. import ================== Pythonはその基本に, - small core language - extra functionality in separate libraries or modules を持ちます. 例えば,平方根を計算する関数は,Pythonにはありません.(表現がアヤシイ) この場合,moduleから関数を ``import`` します.例えば, ``math`` を ``import`` してみましょう. :: >>> import math >>> math.sqrt(4) 2.0 となります. 他にも, ``numpy`` (ナンパイ)にも同じような関数が入っていますが, ``nampy`` は ``list`` に対しても同じ計算を行える点が異なります. :: >>> numpy.sqrt([1,4,16,64]) array([ 1., 2., 4., 8.]) 試しに, ``math`` で同じ計算をしてみると, :: >>> math.sqrt([1,4,16,64]) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) in () ----> 1 math.sqrt([1,4,16,64]) TypeError: a float is required .. Input and Output ================================ .. Pythonで分析を行う上で,テキストファイルを読み込んだり,作成したりする必要性が出てきます. .. まずは, ``newfile.txt`` というファイルを読み込んでみましょう. .. :: .. (ここは飛ばしてる・・・・) Iterating ================================ computingにおける,最も重要なtaskの一つに,繰り返しを用いた処理があります. Pythonの強みの一つは,そのシンプルさと柔軟性にあります. 例えば,繰り返しの処理は ``for`` と ``in`` を使って,表現します. その一例として, ``us_cities.txt`` という都市とその人口のデータの処理をしてみましょう. :: new york: 8244910 los angeles: 3819702 chicago: 2707120 houston: 2145146 philadelphia: 1536471 phoenix: 1469471 san antonio: 1359758 san diego: 1326179 dallas: 1223229 都市とその人口の間には, ``:`` があるので,それを基準にして,都市名と人口を切り離します. 人口には,1000ごとに ``,`` で区切りましょう. まずは,データを読み込みます. ``us_cities.txt`` を,同じディレクトリに置いて, :: >>> data_file = open('us_cities.txt', 'r') とします.次に,繰り返し処理を施し, :: >>> for line in data_file :# data_fileの中で,line(行)ごとに処理を行う >>> city, population = line.split(':') # Tupleをunpackする >>> city = city.title()# 都市のの頭文字を大文字にする >>> population = '{0:,}'.format(int(population))# 数字に','を入れる >>> print(city.ljust(15) + population) ``title()`` は単語の先頭を大文字に,する組み込み関数です. 例えば, :: >>> 'But cOme ye bAck wHen Summers in the meaDow.'.tilte() 'But Come Ye Back When Summers In The Meadow.' となります. Looping without Indices --------------------------------------- 気付いている人もいると思いますが,Pythonでは,ループ処理(looping)を行うとき ``index`` を使わない方が好まれます. 例えば, :: >>> for x in x_values: print x*x というコードのほうが, :: >>> for i in range(len(x_values)): >>> print x_values[i] 8 x_values[i] というコードよりも良いことが,2つを比べてみればわかると思います. Pythonでは,1つ目のコードのように,変数に対して ``i`` のような ``index`` を付けずにループ(looping)処理をシンプルにします. その例の一つとして, ``zip()`` という関数を説明しましょう. ``zip()`` は2つの列の要素を対応させていく関数です. :: >>> zip((1,2,3,4),("a","b","c")) [(1, 'a'), (2, 'b'), (3, 'c')] というように,この場合,2つの ``tuple`` を要素ごとに組み合わせて, ``tuple`` を作り, ``list`` をつくります. この関数を使って,県庁所在地を対応させるコードを書いてみましょう.(教科書では,国と首都を対応させるコードですが,ここで紹介するのもと同じものです) まずは,2つのデータ, ``都道府県のデータ;prefectures`` , ``県庁所在地のデータ;cities`` を用意します. :: >>> prefectures =('北海道(ほっかいどう)','青森県(あおもり)','岩手県(いわて)','宮城県(みやぎ)') >>> cities = ('札幌(さっぽろ)','青森(あおもり)','盛岡(もりおか)','仙台(せんだい)') 次に,この2つを ``zip()`` で対応させていきます. :: >>> prefectures =('北海道(ほっかいどう)','青森県(あおもり)','岩手県(いわて)','宮城県(みやぎ)') >>> cities = ('札幌(さっぽろ)','青森(あおもり)','盛岡(もりおか)','仙台(せんだい)') >>> for prefecture, city in zip(prefectures, cities): print '{0}の県庁所在地は,{1}です'.format(prefecture, city) すると,出力は, :: 北海道(ほっかいどう)の県庁所在地は,札幌(さっぽろ)です 青森県(あおもり)の県庁所在地は,青森(あおもり)です 岩手県(いわて)の県庁所在地は,盛岡(もりおか)です 宮城県(みやぎ)の県庁所在地は,仙台(せんだい)です ``'{0}の県庁所在地は,{1}です'`` の ``{}`` は ``zip()`` で作った,対応を当てはめていく場所です. ``{0}`` と書くと,そこに, ``zip(0, 1)`` とした第0番目の要素が入ります. ``{0}`` の中に,何も書かなかった場合は ``zip(0, 1)`` の要素の順番通りに変数が当てはめられていきます. 例えば, :: >>> print '{}の県庁所在地は,{}です'.format(prefecture, city) としても,結果は変わらず, :: 北海道(ほっかいどう)の県庁所在地は,札幌(さっぽろ)です 青森県(あおもり)の県庁所在地は,青森(あおもり)です 岩手県(いわて)の県庁所在地は,盛岡(もりおか)です 宮城県(みやぎ)の県庁所在地は,仙台(せんだい)です となります. また. :: >>> print '{1}の県庁所在地は,{0}です'.format(prefecture, city) とすれば,:: 札幌(さっぽろ)の県庁所在地は,北海道(ほっかいどう)です 青森(あおもり)の県庁所在地は,青森県(あおもり)です 盛岡(もりおか)の県庁所在地は,岩手県(いわて)です 仙台(せんだい)の県庁所在地は,宮城県(みやぎ)です となり,都道府県と県庁所在地の順番が入れ替わります. zip()とdictionaries ------------------------------ ``zip()``は ``dictionary`` を作るのに便利です. 例えば, :: >>> names = ['Tom', 'John'] >>> marks = ['E', 'F'] >>> dict(zip(names, marks)) {'John': 'F', 'Tom': 'E'} というように,簡単にdictionary type のデータを作ることが出来ました. それでも.indexが必要な時は ---------------------------------------- ``index`` がなくても,ループ処理ができるといっても,実際には ``index`` が必要な時があります. そのような場合は, ``enumerate()`` を用いて, ``index`` を割り当てていきましょう. :: >>> prefecture_list=['北海道(ほっかいどう)','青森県(あおもり)','岩手県(いわて)','宮城県(みやぎ)'] >>> for index, prefecture in enumerate(prefecture_list): >>> print '日本の東から{0}番目の都道府県は,{1}です'.format(index, prefecture) とすれば, :: 日本の東から0番目の都道府県は,北海道(ほっかいどう)です 日本の東から1番目の都道府県は,青森県(あおもり)です 日本の東から2番目の都道府県は,岩手県(いわて)です 日本の東から3番目の都道府県は,宮城県(みやぎ)です と出力されます.ここから, ``{0}`` に ``index`` が割り当てられていることがわかります. ところで,この, ``enumerate()`` では, ``index`` の開始番号を指定することができましょう. ``'日本の東から0番目の都道府県'`` という日本語は,違和感があるので, ``enumerate(prefecture_list,1)`` とすれば. :: >>> for index, prefecture in enumerate(prefecture_list,1): >>> print '日本の東から{0}番目の都道府県は,{1}です'.format(index, prefecture) 日本の東から1番目の都道府県は,北海道(ほっかいどう)です 日本の東から2番目の都道府県は,青森県(あおもり)です 日本の東から3番目の都道府県は,岩手県(いわて)です 日本の東から4番目の都道府県は,宮城県(みやぎ)です というように出力されることから,indexが1から割り当てられていることがわかります. Comparisons and Logical Operators ========================================================= Comparisons -------------------------- Booolean values(True or False で評価されるvalues) として,処理されるものはたくさんあります. ここでは,代表的なものを紹介します. まずは,不等式. :: >>> a,b,c,d,e,f = 1,1,2,3,5,8 >>> a<=b>> x=1 >>> x==20 False ノットイコール \(\neq)\ は, ``!=`` で表現されます. :: >>> 1!=20 True ``if`` を使うと,ある条件が満たされるかどうかで,場合分けすることができます. :: >>> x= 'yes' if 5>2 else 'no' x 'yes' この条件式には,Pythonで認められているものであれば,どんなものでも許容されます. ``if`` のあとに,つねに成立するような命題をいれてみます. :: >>> x= 'yes' if 42 else 'no' >>> x 'yes' 常に満たされない,ものとして, ``if`` のあとに空集合を入れてみましょう. :: >>> x= 'yes' if [] else 'no' >>> x 'no' また, ``if`` の後に ``0`` を入れても同じ結果になります. つまり, ``0`` だけではなく, ``[]`` にも ``false`` が割り当てられているということです. ``bool()`` を用いて,確認してみましょう. :: >>>print(bool(0)) False >>>print(bool(42)) True >>>print(bool([])) False >>>print(bool([1,2,3])) True 条件式は ``and`` を用いて,複数の命題を組み合わせることもできます. :: >>> 1<2 and 'あ' in 'あきら' True More Functions ================================ 今まで紹介していないfunctionとして, ``max()`` , ``min()`` , ``ramge()`` などがあります. range()引数に指定した長さのlistを作ります.例えば, :: >>> range(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] となり,指定しない場合は0から始まるlistを作ります. 始めと終わりの数字を指定することもできます, :: >>> range(-10,10) [-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 次に, ``max()`` は ``list`` や ``tuple`` といった引数の最大値を返す関数です.今までの,条件式や ``range()`` を組み合わせて例を作ると :: >>> max(range(100))>98 True となります. ``range(100)`` は0から99までの ``list`` を作るので, :: >>> max(range(100))>99 False となることが分かります. 最後に, ``str()`` は引数に指定した値の文字列を作ります. :: >>> str(12) '12' Why Write Functions? ================================ 関数(function)を書くことで,コードを明瞭に書くことができます. なぜなら, - ロジックごとにまとまりを作れる - 一度書けば,そのコードを何回も呼び出して使える からです. functionの定義の仕方を示しましょう. 引数の正負を調べる関数を定義します :: def f(x): if x < 0: return 'nagetive' return 'nonnegative' とすれば, :: >>> f(-5) 'nagetive' ``lamba`` を使うと,一行でfunctionを書くこともできます. :: >>> f = lambda x: x**2 とすると, :: >>> f(x=5) 25 のような関数を定義できます. しかし,functionの内容を明確化するためにも, ``def`` をつかったfunctionの定義を用いるほうが望ましいでしょう. Exercises ================================ Exercise1 Par1 ----------------------------- ``zip()`` を使って内積を求める問題 適当な ``list`` の内積を求める :: >>> x=[1.0,1.0,2.0,3.0,5.0,8.0,13.0,21.0,34.0,55.0,89] >>> y=[1,1,2,3,5,8,13,21.0,34.0,55.0,89.0] この2つの ``list`` の内積を求めてみよう :: >>> S=0 #Sを0にしておく >>> for a,b in zip(x,y): #zip()でx,yの要素をa,bに入れる >>> S=S + a*b #for を使って各要素を足しあわせていく >>> print(S) #Sの値を出す 12816.0 問題では ``zip()`` を用いましたが,一行で書くこともできます. ``sum()`` の中に条件式を入れることもできるので :: >>> sum(a*b for a,b in zip(x,y)) 12816.0 とかける. Exercise1 Par2 ----------------------------- 一行で0から99の偶数の数を計算する. ちなみに, :: >>> x%2 という操作が,xを2で割った余りを返すことがヒントです. まず,コードの内容を把握するために,複数行で書いてみる. :: >>> s=0 >>> for x in range(100): >>> if x%2==0: >>> s=s+1 >>> print(s) 50 これを,一行にまとめる. Exercise1 Par1のように ``sum()`` を用いて表現する. ``range(100)`` のなかで, ``x%2==0`` が ``true`` の回数を数えればいいので, :: >>> sum(1 for x in range(100) if x%2==0) 50 xが偶数の時に ``x%2`` が0になることを利用する方法もある. 0にはFalseが割り当てられるので,xが偶数なら ``not x%2`` は ``true`` になる. ``true`` には1が割り当てられているので, :: >>> sum(not x%2 for x in range(100)) 50 Exercise1 Par3 ----------------------------- ``pairs = ((2, 5), (4, 2), (9, 8), (12, 10))`` というリストの ``tuple`` の(a,b)のうち,a,bのどちらもが偶数の ``tuple`` の数を数える. (a,b)のa,bに関してそれぞれ条件式をかくので,(a,b)を分ける必要がある. それは, :: >>> for a,b in pairs とすればよい.あとは条件式をかいてそれが満たされる回数を数えれば良いので, :: >>> pairs=((2,5),(4,2),(9,8),(12,10)) >>> n = 0 >>> for a,b in pairs: >>> if a%2==0 and b%2==0: >>> n=n+1 >>> print(n) 2 とすれば良い. これも,一行でかけて, :: >>> sum(1 for a,b in pairs if a % 2==0 and b%2==0 ) 2 となる. Exercise2 ----------------------------- Polynominal(多項)の式を計算する関数を作るExersise. 式は以下の通り, .. math:: p(x) = a_0 + a_1 x +a_2x^2+ ... + a_nx^n = \sum^n_{i=0} a_i x^i 所与の数列 :math:`a_nとx^n` の掛け算を足し合わせてできる関数p(x)を作れば良い. 数列が所与といっても,それはPolynominal(多項)の式自体がそうなのであって,計算するにはその具体的な値が必要です.なので,関数の引数としては,xの値と,数列anを ``list`` として指定します. 数列のnとxの乗数が共通しているのでそれを利用して書いてみましょう.一番,思いつきやすいのは,項をterとおいて,足しあわせていき,足し合わせるごとのnを1増やしていく方法だと思います. :: >>> def p(x, coeff): >>> n, ter = 0, 0 >>> for a in coeff: >>> ter = ter + (a * (x**n)) >>> n += 1 >>> return ter しかし,先に習ったように, ``enumerate()`` を用いれば, ``index`` をわざわざ作る必要はありません. :: >>> def p2(x, coeff): >>> ter = 0 >>> for n,a in enumerate(coeff): >>> ter = ter + (a * (x**n)) >>> return ter もう少し工夫すれば,この関数を2行で書くこともできます. :: >>> def p3(x, coeff): >>> return sum(a*(x**n) for n,a in enumerate(coeff)) Exercise3 ----------------------------- 英文の文字列の中の大文字の数を数える関数を作る問題です. ヒントとして,文字列を大文字にして返す関数, ``.upper()`` が与えられているので,これを上手く使いましょう. 関数の流れとしては,文字列, ``strings`` の中の文字xを一文字づつ取り出して,その文字の大文字を ``.upper()`` で作ります. そして,それが取り出したxと同じかどうかを調べ,同じだった回数を数えればよいでしょう. :: >>> def f(string): >>> n=0 >>> for x in string: >>> if x == x.upper() and x.isalpha(): >>> n=n+1 >>> return n ただし,この関数の定義をみればわかるように, ``x.isalpha()`` というmethodが用いられています. これは,文字が英字であるかどうかを調べるmethodです. もし,これがないと,スペースやピリオドといった,英字でないものに対してもTrueを返してしまい,正確にstringsの中の大文字の数を数えることはできません. しかし,このような教科書に出ていないmethodを使わなくても,工夫して同じ関数を定義することができます. :: >>> upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' >>> 'A' in upper True このように,あらかじめ,大文字の英字を文字列として与えてこのなかのどれかと,stringの文字が同じだった時,Trueを返すようにすればよいのです. また,Trueの値が1であるということを思い出せば,直接Trueを合計すればいいことにも気づくでしょう. :: >>> def count_upper(s): >>> upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' >>> return sum(c in upper for c in s) Exercise4 ----------------------------- 2つの流列(sequence)a,b,が与えられていて,aの要素すべてが,bの要素に含まれていたらTrueを返す関数をつくる問題. ここでいう,流列とはlistやtuple,stringを意味する. また,setsやset methodを使わずに関数を定義するように指示されています. seq_aの要素を1つずつ取り出して,それが,seq_bの中に入っていなければFalse,それ以外ならばTrueをかえす関数を書いてみましょう. :: >>> def f(seq_a,seq_b): >>> for a in seq_a: >>> if a not in seq_b: >>> return False >>> return True この関数の問題点は,seq_aの要素全てに対して,それがseq_bに属しているかを調べている点です. 問題文では,“の要素すべてが,bの要素に含まれていたらTrue”とあるので,seq_aなかで,一つでもseq_bに入っていないものを見つけたら,すぐにFalseになる関数を書けば,より効率的な関数を書くことができます. そのような,関数を定義するために,all()という組み込み関数を用います. all()は,iterable の全ての要素が真ならば (もしくは iterable が空ならば) True を返すので,bにないものが見つかった時点で,動作をやめます. つまり,seq_aの要素全てに対して,それがseq_bに属しているかを調べている最初の解答例よりも早く処理が終わります. :: >>> def f(seq_a,seq_b): >>> return all(a in seq_b for a in seq_a)