リストと文字列 編集

リストの要素は、文字列だけ、あるいは数値だけでも、かまいません。

文字列だけのリストの場合、たとえば

コード例
myList = ["aaa" ,"bb" ,"cccc"]
myList[0] = 4
print(myList)
実行結果
[4, 'bb', 'cccc']

また、リストは数値と文字が下記のように混在することも、別々の項なら可能です。

コード例
myList = [12 ,"bb" , 84]

print(myList[0] +5)
実行結果
17

他のプログラミング言語だと、数値と文字列とが混在するデータ構造をつくるのにクラスを使わないといけない言語もありますが、しかしPythonではクラスを使わずとも、リストだけで数値との共存が可能です。

for文との組み合わせ 編集

リストは、for文の対象となるコレクションとして使えます。

コード例
names = ["yamada" ,"sato" ,"inoue"]  # 人名リスト

for i in names :
    print(i)
実行結果
yamada
sato
inoue


要素の追加 編集

リストの要素に、あとから追加することもできます。

myList = ["aaa" ,"bb" ,"cccc"]
myList.append("d")
print(myList)
実行結果
['aaa', 'bb', 'cccc', 'd']

python のリストを希望の数だけ予め確保するには、myList = [0] * 100 の様に、初期値を持った配列に乗算演算子を作用し、所望の個数を指定した式の値を与えます。

勿論、律儀に要素を1つづつ追加する方法も有効です。

myList = []

myList.append(123)
myList.append(5)

print(myList)
実行結果
[123, 5]

要素の削除 編集

リストの要素を、あとから削除することもできます。次のコードのようにpop()を使うと、リスト末尾の要素を削除できます。

myList = ["aaa" ,"bb" ,"cccc"]
myList.pop()
print(myList)
実行結果
['aaa', 'bb']

要素の末尾を削除したいリストのうしろに「.pop()」をつけ、ることで、要素の末尾を削除していけます。

なお、この.pop()のような、操作したい対象物のうしろにドット記号(.)と操作内容のキーワードをつける特別な関数のことをpythonでは、「メソッド」といいます。


myList.pop()をくりかえすと、さらに末尾から、削除していきます。

myList = ["aaa" ,"bb" ,"cccc"]
myList.pop()
myList.pop()
print(myList)
実行結果
['aaa']


リストの要約 編集

リスト( list )は、任意のオブジェクトをゼロ個以上、順次付けて保持できるコレクションです[1]

リストリテラル 編集

リストリテラル
print(f"""\
{[]=}
{list()=}
{list((1,2,3))=}
{list(i for i in range(5))=}
{[10,"ABC"]=}
{[[1,"one"], [2,"two"],[3,"three"]]=}
{[
    [1,"壱"],
    [2,"弐"],
    [3,"参"]
    ]=}
""")
実行結果
[]=[]
list()=[]
list((1,2,3))=[1, 2, 3]
list(i for i in range(5))=[0, 1, 2, 3, 4]
[10,"ABC"]=[10, 'ABC']
[[1,"one"], [2,"two"],[3,"three"]]=[[1, 'one'], [2, 'two'], [3, 'three']]
[
    [1,"壱"],
    [2,"弐"],
    [3,"参"]
    ]=[[1, '壱'], [2, '弐'], [3, '参']]

リストは、要素を ,(カンマ) で区切り全体を [ ] で囲みます。 要素の型は同じである必要はありません。

リストと演算子 編集

リストと演算子
li = [10 ,"ABC" ,30]
print(f'''\
{li=}
{li[1]=}
{li[-1]=}
{li + [2,3,4]=}
{li * 2=}
{2 * li=}
{li == [10 ,"ABC" ,30]=}
{li != [10 ,"ABC" ,30]=}
{li < [10 ,"ABC" ,30]=}
{li > [10 ,"ABC" ,30]=}
''')
実行結果
li=[10, 'ABC', 30]
li[1]='ABC'
li[-1]=30
li + [2,3,4]=[10, 'ABC', 30, 2, 3, 4]
li * 2=[10, 'ABC', 30, 10, 'ABC', 30]
2 * li=[10, 'ABC', 30, 10, 'ABC', 30]
li == [10 ,"ABC" ,30]=True
li != [10 ,"ABC" ,30]=False
li < [10 ,"ABC" ,30]=False
li > [10 ,"ABC" ,30]=False
リストの要素は、インデックス演算子で参照できます。
リスト内の要素の順位はタプルやレンジと同じく、0番から始まります。
負のインデクスiは、len(self)+iを表します。
リスト同士の足し算は、連結した新しいリストを返します。
リストtと整数nとの乗算は、tをn回繰り返したリストを返します。
整数nとリストtとの乗算は、tをn回繰り返したリストを返します。
リスト同士は、比較や大小判別ができます。

リストはミュータブル 編集

リストの各要素を、代入・置き換えすることもできます。

myList = [10 ,"ABC" ,30]
myList[0] = 4
print (myList)
実行結果
[4, 'ABC', 30]
です。「10」が「4」に置き換わっています。

多次元リスト 編集

リストの中にリストを入れることも出来ます。ただし、下記のように入れたリストの項目数が等しくなるようにする必要があります。

リストの中にリストを入れたものを2次元リスト(または2重リスト)といい、

リストの中にリストを入れたもののなかに、さらにリストを入れたものを3次元リストと言います。

二次元リストのコード例
carList = [ ["山田" , "red" , 1234 ] , ["伊藤" , "blue" , 555 ]    ]

print(carList[0][0] )
print(carList[0][1] )
print(carList[1][0] )
実行結果
山田
red
伊藤

map関数 編集

組込み関数mapを使うと、iterableオブジェクトの全ての要素に、一括で何かの関数を適用する事ができます。

関数宣言
map(function, iterable)
コード例
myList = [-7 , -2, 5]

print(f'''\
{myList=}
{map(abs, myList)=}
{list(map(abs, myList))=}
{list(abs(x) for x in myList)=}
{[abs(x) for x in myList]=}
{[-x if x < 0 else x for x in myList]=}
''')
実行結果
myList=[-7, -2, 5]
map(abs, myList)=<map object at 0x149ab6e4c0d0>
list(map(abs, myList))=[7, 2, 5]
list(abs(x) for x in myList)=[7, 2, 5]
[abs(x) for x in myList]=[7, 2, 5]
[-x if x < 0 else x for x in myList]=[7, 2, 5]
リスト myList の要素の絶対値を得るプログラムです。
map関数の第一引数は関数が要求されますが、1つの引数を取り値を帰っす必要があります。ここでは組込み関数absを使いました。
map関数はリスト...ではなく map object を返します。
map objectはリストコンストラクタであるlist関数でリスト化できます。
map関数はジェネレーター式(function(x) for x in iterable)と等価です。
またリスト化するなら、リスト内包表記[function(x) for x in iterable]と等価です。
内包表記であれば、absの呼出しは条件演算子-x if x < 0 else xで置換える事ができます。

abs のような組込み関数だけでなく、ユーザー定義関数やlambdaもmap関数の第一引数にすることができます。

filter関数 編集

組込み関数filterは、iterableオブジェクトの要素の中から、条件に適合するものだけを選び出して、新たなリストを作ります、

関数宣言
filter(function, iterable)
引数
function
残すかの条件関数False以外を返すと残す
iterable
対処とするiterableオブジェクト
コード例
myList = [5, 2, 8, 3, 6, 1]

print(f'''\
{myList=}
{filter(lambda x:x >= 3, myList)=}
{list(filter(lambda x:x >= 3, myList))=}
{list(x for x in myList if x >= 3)=}
{[x for x in myList if x >= 3]=}
''')
実行結果
myList=[5, 2, 8, 3, 6, 1]
filter(lambda x:x >= 3, myList)=<filter object at 0x154a32dccd00>
list(filter(lambda x:x >= 3, myList))=[5, 8, 3, 6]
list(x for x in myList if x >= 3)=[5, 8, 3, 6] 
[x for x in myList if x >= 3]=[5, 8, 3, 6]
リスト myList から3より多い要素を残すプログラムです。
filter関数の第一引数は関数を要求されますが、名前は不要で繰返し使う予定もないので lambda を使いました。
filter関数はリスト...ではなく filter object を返します。
filter objectはリストコンストラクタであるlist関数でリスト化できます。
filter関数はジェネレーター式(x for x in iterable if function(x))と等価です。
またリスト化するなら、リスト内包表記[x for x in iterable if function(x)]と等価です。

filter関数の第一引数をNoneとした場合 編集

コード例
myList = [5, set(), 8, "", 3, False, 6, None, 1, tuple(), 0, 3, []]

print(f'''\
{myList=}
{filter(None, myList)=}
{list(filter(None, myList))=}
{list(x for x in myList if x)=}
{[x for x in myList if x]=}
''')
実行結果
myList=[5, set(), 8, '', 3, False, 6, None, 1, (), 3, []]
filter(None, myList)=<filter object at 0x1514a15ee0d0>
list(filter(None, myList))=[5, 8, 3, 6, 1, 3]
list(x for x in myList if x)=[5, 8, 3, 6, 1, 3]
[x for x in myList if x]=[5, 8, 3, 6, 1, 3]
リスト myList からfalsy[2]でない要素を残すプログラムです。
filter関数の第一引数は関数を要求されますが、Noneを渡すとfalsyな要素を除去します。
この場合も、filter関数はリスト...ではなく filter object を返します。
この場合も、filter objectはリストコンストラクタであるlist関数でリスト化できます。
この場合は、filter関数はジェネレーター式(x for x in iterable if x)と等価です。
この場合はリスト化するなら、リスト内包表記[x for x in iterable if x]と等価です。

リスト内包表記を使った例 編集

上記のmap関数とfilter関数の使用例はリスト内包表記をつかうと

コード例
myList = [-7 , -2, 5]
obj = [abs(i) for i in myList]
print(obj)

myList = [5, 2, 8, 6, 1]
obj = [i for i in myList if i >= 3]
print(obj)

と表現できます。 for式やif式、if-else式(条件演算子)はリスト内包表記と組合わせると関数呼出しを使わないでもイテレーションやケース分けができます。

絶対値を求める部分も、

obj = [-i if i < 0 else i for i in myList]

とインラインで表現できます。

リストのフィールド一覧 編集

リストのフィールド一覧
obj = []
for i in dir(obj):
    print(i, eval(f"type({obj}.{i})"))
実行結果
__add__ <class 'method-wrapper'>
__class__ <class 'type'>
__contains__ <class 'method-wrapper'>
__delattr__ <class 'method-wrapper'>
__delitem__ <class 'method-wrapper'>
__dir__ <class 'builtin_function_or_method'>
__doc__ <class 'str'>
__eq__ <class 'method-wrapper'>
__format__ <class 'builtin_function_or_method'>
__ge__ <class 'method-wrapper'>
__getattribute__ <class 'method-wrapper'>
__getitem__ <class 'builtin_function_or_method'>
__gt__ <class 'method-wrapper'>
__hash__ <class 'NoneType'>
__iadd__ <class 'method-wrapper'>
__imul__ <class 'method-wrapper'>
__init__ <class 'method-wrapper'>
__init_subclass__ <class 'builtin_function_or_method'>
__iter__ <class 'method-wrapper'>
__le__ <class 'method-wrapper'>
__len__ <class 'method-wrapper'>
__lt__ <class 'method-wrapper'>
__mul__ <class 'method-wrapper'>
__ne__ <class 'method-wrapper'>
__new__ <class 'builtin_function_or_method'>
__reduce__ <class 'builtin_function_or_method'>
__reduce_ex__ <class 'builtin_function_or_method'>
__repr__ <class 'method-wrapper'>
__reversed__ <class 'builtin_function_or_method'>
__rmul__ <class 'method-wrapper'>
__setattr__ <class 'method-wrapper'>
__setitem__ <class 'method-wrapper'>
__sizeof__ <class 'builtin_function_or_method'>
__str__ <class 'method-wrapper'>
__subclasshook__ <class 'builtin_function_or_method'>
append <class 'builtin_function_or_method'>
clear <class 'builtin_function_or_method'>
copy <class 'builtin_function_or_method'>
count <class 'builtin_function_or_method'>
extend <class 'builtin_function_or_method'>
index <class 'builtin_function_or_method'>
insert <class 'builtin_function_or_method'>
pop <class 'builtin_function_or_method'>
remove <class 'builtin_function_or_method'>
reverse <class 'builtin_function_or_method'> 
sort <class 'builtin_function_or_method'>

リストと演算子 編集

リストと演算子
print(f'''\
{[1,2,3] + [7,8,9] =}
{[1,2,3] * 2 =}
{2 in [1,2,3] =}
{[1,2,3] == [7,8,9] =}
{[1,2,3] == [1,2,3] =}
{[1,2,3] != [7,8,9] =}
{[1,2,3] != [1,2,3] =}
{[1,2,3] > [1,2] =}
{[1,2,3] < [1,2] =}
''')

import operator

print(f'''\
{operator.__add__([1,2,3], [7,8,9]) =}
{operator.__mul__([1,2,3], 2) =}
{operator.__contains__([1,2,3],2)=}
{operator.__eq__([1,2,3], [7,8,9]) =}
{operator.__eq__([1,2,3], [1,2,3]) =}
{operator.__ne__([1,2,3], [7,8,9]) =}
{operator.__ne__([1,2,3], [1,2,3]) =}
{operator.__gt__([1,2,3], [1,2]) =}
{operator.__lt__([1,2,3], [1,2]) =}
''')

print(", ".join(vars(operator)))
実行結果
[1,2,3] + [7,8,9] =[1, 2, 3, 7, 8, 9]
[1,2,3] * 2 =[1, 2, 3, 1, 2, 3]
2 in [1,2,3] =True
[1,2,3] == [7,8,9] =False
[1,2,3] == [1,2,3] =True
[1,2,3] != [7,8,9] =True
[1,2,3] != [1,2,3] =False
[1,2,3] > [1,2] =True
[1,2,3] < [1,2] =False

operator.__add__([1,2,3], [7,8,9]) =[1, 2, 3, 7, 8, 9]
operator.__mul__([1,2,3], 2) =[1, 2, 3, 1, 2, 3]
operator.__contains__([1,2,3],2)=True
operator.__eq__([1,2,3], [7,8,9]) =False
operator.__eq__([1,2,3], [1,2,3]) =True
operator.__ne__([1,2,3], [7,8,9]) =True
operator.__ne__([1,2,3], [1,2,3]) =False
operator.__gt__([1,2,3], [1,2]) =True
operator.__lt__([1,2,3], [1,2]) =False

__name__, __doc__, __package__, __loader__, __spec__, __file__, __cached__, __builtins__, __all__, _abs, lt, le, eq, ne, ge, gt, not_, truth, is_, is_not, abs, add, and_, floordiv, index, inv, invert, lshift, mod, mul, matmul, neg, or_, pos, pow, rshift, sub, truediv, xor, concat, contains, countOf, delitem, getitem, indexOf, setitem, length_hint, attrgetter, itemgetter, methodcaller, iadd, iand, iconcat, ifloordiv, ilshift, imod, imul, imatmul, ior, ipow, irshift, isub, itruediv, ixor, __lt__, __le__, __eq__, __ne__, __ge__, __gt__, __not__, __abs__, __add__, __and__, __floordiv__, __index__, __inv__, __invert__, __lshift__, __mod__, __mul__, __matmul__, __neg__, __or__, __pos__, __pow__, __rshift__, __sub__, __truediv__, __xor__, __concat__, __contains__, __delitem__, __getitem__, __setitem__, __iadd__, __iand__, __iconcat__, __ifloordiv__, __ilshift__, __imod__, __imul__, __imatmul__, __ior__, __ipow__, __irshift__, __isub__, __itruediv__, __ixor__
モジュールoperatorを使うと、演算子を関数形式で呼び出すことができます[3]

他のプログラミング言語との比較 編集

他のプログラミング言語とPythonの類似点と差異をリストを中心に比較します。

Python
compound = [ 10, 20, 30 ]
Ruby
compound = [ 10, 20, 30 ]
完全に一致
JavaScript
let compound = [ 10, 20, 30 ]
let があること以外同じ
JavaScript(TypedArray)
let compound = new Int32Array([10,20,30])
ECMAScript 2015(ES6)でTypedArray(型付き配列)が追加されました。
TypedArrayはJSの配列とは違い、単一要素型で連続したメモリーに割当てられます。
C言語
int compound[] = { 10, 20, 30 };
だいぶ違う
意味的にも、C言語の配列は全ての要素の型は同一で連続したメモリーに割り付けられます。
Go(配列)
compound := [...]int{ 10, 20, 30 }
C言語ともだいぶ違う
意味的には、C言語の配列と同じく全ての要素の型は同一で連続したメモリーに割り付けられます。
Go(スライス)
compound := []int{ 10, 20, 30 }
よく似た構文ですが [ ] の中に ... がないのはスライス
スライスの要素は離散的なアドレスに配置され、動的に長さ(要素数)の変更が可能です。

宣言と初期化の部分に注目し様々な差異がありましたが、要素の参照は、

Python
compound[1]

の構文で、この部分はどの言語でもほぼ同じですが、FortranBASICでは、

Fortran, BASIC
compound(1)

のように丸括弧になります。

それぞれの言語のリストに似た型

Pythonに「配列」というデータ型は存在しません[4]。C言語などに、配列というデータ型があります。

言語によっては、「配列」データ型と「リスト」データ型とが別個に存在するものもあります(たとえば Kotlin という言語には、配列(array)データ型と、リスト list データ型とが別々に存在します) なお、kotlin は現在では、Android スマートホンのアプリケーションプログラムの開発などで、よく使われる言語です。

また、Goには「リスト」はなく「スライス」slice があります(Goのスライスの機能はPythonやkotlinの「リスト」と一見似ていますが、Goのスライスは「要素の型が一致している必要がある」ので本質的に「リスト」とは違い、異種リストの実装には interface{} を使います)。

Goには、配列型と「スライス」slice の2つのデータ型がありよく混同されますが、スライスは要素のアクセスは線形時間 O(n)、配列の要素のアクセスは定数時間 O(1)であることが大きな違いです。

要素の参照速度による分類 編集

リストや配列に類似した型は、要素の参照にかかる時間によって

線形時間 O(n)が必要なもの
Pythonのリスト、Goのスライスはこれに当たります
個々の要素の型は異なっても良い
要素数の増減可能
定数時間 O(1)で済むもの
Pythonの標準モジュールの array や拡張モジュール NumPy、JavaScriptのTypedArray、C言語の配列、Goの配列
個々の要素の型は一致している必要がある
要素数は宣言時に確定する
宣言時の要素数に定数式しか受け付けない言語(過去のC言語やGo)と、宣言時の要素数に実行時まで確定しない式も受け付ける言語(現在のC言語など)がある


  1. ^ 3.10.1 Documentation » The Python Language Reference » 3. Data model ¶3.2. The standard type hierarchy” (2021年12月16日). 2021年12月16日閲覧。
  2. ^ falsy: 組込み関数bool() に与えると False を返すような式。False, None の他、空集合(set())、空文字列()、0、空タプル(tuple())、空リスト([])など
  3. ^ operator — Standard operators as functions — Python 3.10.1 documentation” (2021年12月15日). 2021年12月15日閲覧。
  4. ^ 標準モジュールの array あるいは、拡張モジュールの NumPy で連続した領域に要素が配置される配列が提供されますが、組込みオブジェクトの配列はありません。