カテゴリー

Python基礎

【python&初級】のlistとかforとかifとかまとめ

2021年6月4日

こんな人にオススメ

pythonの初歩的なlistとかifとかってどうやって書くの?

ひとまとめで一覧できるようにしたい!

ということで、今回は超ロング記事なpythonの初歩的な内容まとめ。listifforなど初歩的な内容の簡単な部分だけを書いているので、python初めたての方も理解しやすいのではないだろうか。

また、挙動に疑問がある場合も本記事で確認可能。辞書的な感じでお使いいただければ幸いだ。なお、処理の一部はpythonのバージョンによっては使えない場合がある。その場合は代替コードに変更していただきたい。

(目次が長いのは節表示をしているためと、本サイトの設定などが目次の折りたたみに対応していないから。ご理解いただけると幸いです。)

python環境は以下。

  • Python 3.9.4
  • numpy 1.20.3

運営者のメガネです。YouTubeTwitterInstagramも運営してます。

自己紹介はこちらから、お問い合わせはこちら。

運営者メガネ

list(リスト)

list(リスト)とは変数をひとまとめにした箱のようなもの。3個くらいなら一つ一つに変数名を割り当ててもいいが、これが1000などになると変数名の割り当てや記述、管理が大変になる。

ということでそれらをまとめてlistにして一括管理しようというわけだ。過去にも記事を出しているのでそちらも参考にしていただければと思う。

【python&list】pythonのlistの超基礎

こんな人にオススメ pythonのlistっ& ...

続きを見る

listの作り方

list[]でくくるかlist()にする。

# listの作り方
lst = [0, 1, 2]
print(lst)
# [0, 1, 2]
print(type(lst))
# <class 'list'>

lst = list((0, 1, 2))
print(lst)
# [0, 1, 2]
print(type(lst))
# <class 'list'>

range関数を使えば連続的に作成可能。

lst = list(range(10))
print(lst)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

list × 数値

listに数値をかけるとlistが複製される。

# 数値の掛け算
lst = [0, 1, 2]
print(lst * 2)
# [0, 1, 2, 0, 1, 2]
print(type(lst))
# <class 'list'>

要素を数値倍したいなら以下のmap関数や、後述のforなどを使用する必要がある。

lst_2 = list(map(lambda x: x * 2, lst))
print(lst_2)
# [0, 2, 4]

また、numpyなら数値倍が可能。型がlistではなくなるのでlistにする必要がある。

import numpy as np
# numpyなら倍数にできる
lst = [0, 1, 2]
arr = np.array(lst)
print(type(arr))
# <class 'numpy.ndarray'>
print(arr * 2)
# [0 2 4]
print((arr * 2).tolist())
# [0, 2, 4]
print(type((arr * 2).tolist()))
# <class 'list'>

list同士の掛け算

list同士の掛け算はできない。

# list同士の掛け算
lst1 = [0, 1, 2]
# lst2 = [10, 20, 30]
# print(lst1 * lst2)
# #     print(lst1 * lst2)
# # TypeError: can't multiply sequence by non-int of type 'list'

numpy.ndarrayなら同じ要素数か要素数1なら掛け算可能。

arr1 = np.array([0, 1, 2])
arr2 = np.array([10, 20, 30])
print(arr1 * arr2)
# [ 0 20 60]

arr3 = np.array([100])
print(arr1 * arr3)
# [ 0 100 200]

arr4 = np.array([100, 1000])
# print(arr1 * arr4)
#     print(arr1 * arr4)
# ValueError: operands could not be broadcast together with shapes (3,) (2,)

要素の追加

.appendで要素を追加。

# 要素を追加
lst = [0, 1, 2]
lst.append(10)
print(lst)
# [0, 1, 2, 10]

# 配列はそのまま入る
lst = [0, 1, 2]
lst.append([10, 20])
print(lst)
# [0, 1, 2, [10, 20]]

listを展開して入れようとするとエラー。listを入れたいなら.extendを使用する。

# append内には1つしかおけない=アンパックするとエラー
lst = [0, 1, 2]
# lst.append(*[10, 20])
# print(lst)
# #     lst.append(*[10, 20])
# # TypeError: list.append() takes exactly one argument (2 given)

lst = [0, 1, 2]
lst.extend([10, 20])
print(lst)
# [0, 1, 2, 10, 20]

もしくはシンプルに足し算。

lst1 = [0, 1, 2]
lst2 = [10, 20, 30]
lst = lst1 + lst2
print(lst)
# [0, 1, 2, 10, 20, 30]

スライス

スライスは簡単に言えば配列(listとか)から規則にしたがって要素を取り出すこと。例えば1番目から8番目までの要素を2つごとに抽出とか。[]を使用して抽出。

# スライス
lst = [0, 1, 2]
lst01 = lst[:2]
print(lst01)
# [0, 1]
lst01 = lst[0:2]
print(lst01)
# [0, 1]

lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
lst345 = lst[3:6]
print(lst345)
# [3, 4, 5]

# 負符号は最後から勘定
lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
lstm1 = lst[-1]
print(lstm1)
# 9
lstfm4 = lst[-4:]
print(lstfm4)
# [6, 7, 8, 9]
lstfm52 = lst[-5:-2]
print(lstfm52)
# [5, 6, 7]

# 何要素飛ばしか指定可能
lststp2 = lst[::2]
print(lststp2)
# [0, 2, 4, 6, 8]
lst36stp2 = lst[3:6:2]
print(lst36stp2)
# [3, 5]

要素の検索

要素の検索には.indexを使用。

# 要素検索
lst = [0, '1', 'two', 3.0]
print(lst)
# [0, '1', 'two', 3.0]

lst_indx0 = lst.index(0)
print(lst_indx0)
# 0
lst_indx1 = lst.index('1')
print(lst_indx1)
# 1
lst_indxtw0 = lst.index('two')
print(lst_indxtw0)
# 2
lst_indxtw3 = lst.index(3.0)
print(lst_indxtw3)
# 3

整数と小数の区別はされない。

# 小数、整数は区別されない
lst_indxtw3 = lst.index(3)
print(lst_indxtw3)
# 3

# 小数、整数は区別されないので初めの1がhit
lst = [1, 2, 1.0, 4]
print(lst.index(1.0))
# 0

存在しない要素を選ぶとエラー。

# 存在しないものはエラー
# lst_indxtw3 = lst.index('3')
# print(lst_indxtw3)
# #     lst_indxtw3 = lst.index('3')
# # ValueError: '3' is not in list

要素の削除

delとスライスで要素を削除することができる。スライスを指定しないと変数ごと削除。

lst = [0, 1, 2]
del lst[0]
print(lst)
# [1, 2]

lst = [0, 1, 2]
del lst[0:2]
print(lst)
# [2]

lst = [0, 1, 2]
del lst[:]
print(lst)
# []

スライスで範囲([0:1]とか)を使用すると= []で削除もできる。

lst = [0, 1, 2]
lst[0:1] = []
print(lst)
# [1, 2]

.remove()で要素名指定で削除。

lst = [0, 1, 2]
lst.remove(2)
print(lst)
# [0, 1]

tuple(タプル)

tuple(タプル)はlistと同じように配列の一種であるが、listとは異なり、()で記述し処理速度は若干早い。しかし、その分要素の変更などができないなどのデメリットがある。

tupleの作り方

tuple(,)で作成するかtuple()で作成。

# tupleの作成
tpl = (1, 2, 3)
print(tpl)
# (1, 2, 3)
print(type(tpl))
# <class 'tuple'>

tpl = tuple((1, 2, 3))
print(tpl)
# (1, 2, 3)
print(type(tpl))
# <class 'tuple'>

tupleには,が必要。,なしで()とするとそれは数値とかになる。

# tupleには,が必要
ng_tpl = (1)
print(ng_tpl)
# 1

print(type(ng_tpl))
# <class 'int'>

ok_tpl = (1,)
print(ok_tpl)
# (1,)

print(type(ok_tpl))
# <class 'tuple'>

要素の追加

基本的tupleの要素の追加ができない。しかし、掛け算で複製はできる。

# 要素追加
tpl = (1, 2, 3) * 2
print(tpl)
# (1, 2, 3, 1, 2, 3)

追加はできない。

# tupleは変更不可なのでappendがない
tpl = (1, 2, 3)
# tpl.append(10)
#     tpl.append(10)
# AttributeError: 'tuple' object has no attribute 'append'

tuple同士の足し算は可能。

# tuple同士の足し算は可能
tpl1 = (0, 1, 2)
tpl2 = (10, 20, 30)
tpl = tpl1 + tpl2
print(tpl)
# (0, 1, 2, 10, 20, 30)

スライス

tupleもスライスによる要素抽出が可能。

# スライス
tpl = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
tpl0 = tpl[0]
print(tpl0)
# 0

tpl05 = tpl[0:5]
print(tpl05)
# (0, 1, 2, 3, 4)

要素の削除

追加同様、削除もできない。

# 要素削除
tpl = (0, 1, 2)
# del tpl[0]
#     del tpl[0]
# TypeError: 'tuple' object doesn't support item deletion

2次元配列

上記の1次元配列では列の情報だけだったが、2次元配列では行の情報が追加される。

listの2次元配列

listのカッコを2にすると2次元配列。

# listの中にlistを書けば2次元配列になる(tupleも同様)
lst = [[1, 2, 3], [10, 20, 30]]
print(lst)
# [[1, 2, 3], [10, 20, 30]]
print(type(lst))
# <class 'list'>
print(len(lst))
# 2

配列の要素はスライスで抽出可能。1つ目のスライスで行を2つ目のスライスで列を抽出可能。

print(lst[0])
# [1, 2, 3]
print(lst[0][2])
# 3

print(lst[0:2])
# [[1, 2, 3], [10, 20, 30]]
print(lst[0:2][1][2])
# 30

1次元の時と同様、数値を掛け算すると複製可能。

# 掛け算をすると複製
print(lst * 2)
# [[1, 2, 3], [10, 20, 30], [1, 2, 3], [10, 20, 30]]

numpy.ndarrayの2次元配列

numpyを使用することでより高速かつ使いやすい配列を作成することができる。

import numpy as np
# numpyのnumpy.ndarrayが一般的
arr = np.array(lst)
# 見た目はリストだがちゃんとnumpy.ndarray
print(arr)
# [[ 1  2  3]
#  [10 20 30]]
print(type(arr))
# <class 'numpy.ndarray'>

スライスはlistの時と同じ。

# 扱い方は2次元listと同じ
print(arr[0])
# [1 2 3]
print(type(arr[0]))
# <class 'numpy.ndarray'>

ただし、数値の掛け算は要素の数値の掛け算になる。

# numpy.ndarrayの場合は掛け算すると倍数に
print(arr * 2)
# [[ 2  4  6]
#  [20 40 60]]

dict(辞書)

listtupleなどは要素だけを記すことができる。一方で、dictではkeysvaluesと結びつけることで対応関係を持つ配列を作成することができる。

dictの作り方

dictkeyvalueを結びつける必要があるので、必ず2種類セットで書く。

# dictの作り方
dct = {'a': 1, 'b': 2, 'c': 3}
print(dct)
# {'a': 1, 'b': 2, 'c': 3}
print(type(dct))
# <class 'dict'>

dct = dict(a=1, b=2, c=3)
print(dct)
# {'a': 1, 'b': 2, 'c': 3}
print(type(dct))
# <class 'dict'>

ただし、dict()を使用して作成する際に、keysに数値を選ぶとエラー。

# {}を使用した時はkeyに数値を使用可能
dct = {'a': 1, 'b': 2, 10: 3}
print(dct)
# {'a': 1, 'b': 2, 10: 3}

# dict()の時にkeyが数値はエラー
# dct = dict(a=1, b=2, 10=3)
#     dct = dict(a=1, b=2, 10=3)
#                          ^
# SyntaxError: expression cannot contain assignment, perhaps you meant "=="?

dictkeysとして使える型

keysには内容が変更されないものを指定しないといけない。

# dictのkeyとして使える型
import datetime
dct = {
    100: 0,
    'A': 1, 'B': 2, '': 3,
    None: 4, (1, 2, 3): 5, datetime.date(2016, 1, 1): 6,
    True: 7, False: 8,
    range(3): 10, range(0, 3): 11, range(0, 3, 1): 12,
    range: 13, type(list): 14, list: 15
}
print(dct)
# {100: 0, 'A': 1, 'B': 2, '': 3, None: 4, (1, 2, 3): 5, datetime.date(2016, 1, 1): 6, True: 7, False: 8, range(0, 3): 12, <class 'range'>: 13, <class 'type'>: 14, <class 'list'>: 15}

listdictsetは中身を変更できるのでkeyに設定できない。

# listなど、変更可能なものはkeysには設定できない
# dct = {list((1, 2, 3)): 10}
#     dct = {list((1, 2, 3)): 10}
# TypeError: unhashable type: 'list'

# dct = {{1, 2, 3}: 30}
#     dct = {{1, 2, 3}: 30}
# TypeError: unhashable type: 'set'

# dct = {{'a': 10}: 40}
#     dct = {{'a': 10}: 40}
# TypeError: unhashable type: 'dict'

keysの取り出し

keysの取り出しはkeysを指定すると可能。

# 値の取り出しはkeyの名前で指定
print(dct[100])
# 0
print(dct['A'])
# 1
print(dct[False])
# 8
print(dct[range(3)])
# 12
print(dct[type])
# 14
print(dct[list])
# 15

keysの一覧は.keys()で行う。

# key一覧は.keys()で指定
keys = dct.keys()

print(keys)
# dict_keys([100, 'A', 'B', '', None, (1, 2, 3), datetime.date(2016, 1, 1), True, False, range(0, 3), <class 'range'>, <class 'type'>])
print(type(keys))
# <class 'dict_keys'>

ただし、keysのままではスライスが使えないので、listに変換。

# .keysのままではスライスが使えない
# print(keys[0])
#     print(keys[0])
# TypeError: 'dict_keys' object is not subscriptable

# listにすればスライスできる
print(list(keys))
# [100, 'A', 'B', '', None, (1, 2, 3), datetime.date(2016, 1, 1), True, False, range(0, 3), <class 'range'>, <class 'type'>]
print(list(keys)[-1])
# <class 'type'>
print(type(list(keys)[-1]))
# <class 'type'>

valuesの取り出し

valuesの一覧は.values()で行う。

# value一覧は.values()で指定
values = dct.values()

print(values)
# dict_values([0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 13, 14, 15])
print(type(values))
# <class 'dict_values'>

このままだとスライスできないので、listに変換。

# keyと同じくvaluesだけではスライスできない
# print(values[0])
#     print(values[0])
# TypeError: 'dict_values' object is not subscriptable

# listにすればスライスできる
print(list(values))
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 13, 14, 15]
print(list(values)[2:6])
# [2, 3, 4, 5]

keys, valuesを同時に取り出し(items

keysvaluesを同時に抽出したい時は.items()で行う。

# keyもvalueもどちらも欲しいならitems()
items = dct.items()

print(items)
# dict_items([(100, 0), ('A', 1), ('B', 2), ('', 3), (None, 4), ((1, 2, 3), 5), (datetime.date(2016, 1, 1), 6), (True, 7), (False, 8), (range(0, 3), 12), (<class 'range'>, 13), (<class 'type'>, 14), (<class 'list'>, 15)])
print(type(items))
# <class 'dict_items'>

スライスもlistにすればいい。

print(list(items))
# [(100, 0), ('A', 1), ('B', 2), ('', 3), (None, 4), ((1, 2, 3), 5), (datetime.date(2016, 1, 1), 6), (True, 7), (False, 8), (range(0, 3), 12), (<class 'range'>, 13), (<class 'type'>, 14), (<class 'list'>, 15)]
print(list(items)[-4])
# (range(0, 3), 12)
print(type(list(items)[-4]))
# <class 'tuple'>
print(list(items)[-4][0])
# range(0, 3)

要素の追加

要素の追加はkeysvaluesを同時に指定しないともちろんいけない。dict[keys] = values

setdefault()を使用する場合は

# 要素の追加
dct = {100: 0, 'A': 1, }

# 要素はkeyとvaluesで追加
dct['new'] = 'NEW'
print(dct)
# {100: 0, 'A': 1, 'new': 'NEW'}

dct.setdefault('new2', 'NEW2')
print(dct)
# {100: 0, 'A': 1, 'new': 'NEW', 'new2': 'NEW2'}

# [key]で追加する場合はvalueは上書き
dct['new'] = 'NEW_2'
print(dct)
# {100: 0, 'A': 1, 'new': 'NEW_2', 'new2': 'NEW2'}

# setdefaultで追加する場合はvalueは上書きされない
dct.setdefault('new2', 'NEW2_2')
print(dct)
# {100: 0, 'A': 1, 'new': 'NEW_2', 'new2': 'NEW2'}

dictの結合(マージ)

dict同士の結合は複数種のdictを新たなdict内でアンパック(展開)することで可能。ただし、dict()形式だとkeysが被るとエラー。

マージについては以下の記事も参照。

【辞書の結合】dictのマージ

こんな人にオススメlistは+記号 ...

続きを見る

# dict同士の結合(マージ)
dct1 = {'A': 1, 'B': 2, '': 3, }
dct2 = {'D': 10, 'E': 20, '': 30, }

# 結合はアンパックで可能
# {}の時はkeyが被ると上書き
print({**dct1, **dct2})
# {'A': 1, 'B': 2, '': 30, 'D': 10, 'E': 20}

# dict()の時はkeyが被るとエラー
# print(dict(**dct1, **dct2))
#     print(dict(**dct1, **dct2))
# TypeError: dict() got multiple values for keyword argument ''

python3.9からは「|」を用いたマージが可能に。

# python3.9からは「|」が使用可能に
print(dct1 | dct2)
# {'A': 1, 'B': 2, '': 30, 'D': 10, 'E': 20}

if(条件分岐)

条件によって内容を変えたい時、例えば偶数ならある処理を、奇数なら別の処理をするときには条件分岐という考え方を使用する。pythonの条件分岐にはifが用いられる。

TrueFalseの判定とは(==>=とか)

まずは条件分岐に必要な条件判定とは何かというものから。これは単純に、その条件に当てはまるかどうかを判定するということ。判定に使用するTrue, Falsebool型と呼ばれる型。

  • 当てはまる = 真: True
  • 当てはまらない = 偽: False
# TrueとFalse
a = 1
b = 2
print(a < b)  # bはaより大きい
# True
print(a > b)  # bはaより小さい
# False
print(a <= b)  # bはa以上
# True
print(a >= b)  # aはb以上
# False
print(a == b)  # aとbは等しい
# False
print(a != b)  # aはbと等しくない
# True

ifelifelse

条件判定は、初めはifで行う。それに当てはまらない条件はelseで条件を分岐させるが、3種類以上に分岐させたいときはifelseの間にelifを入れて条件を追加する。

# ifで条件判定をし、当てはまらない場合は全てelseへ
a = 1
b = 2
if a < b:
    print('bの方が大きい')
else:
    print('aの方が大きい')
# bの方が大きい

# elifで次の条件を追加可能
a = 1
b = 1
if a < b:
    print('bの方が大きい')
elif a == b:
    print('aとbは等しい')
else:
    print('aの方が大きい')
# aとbは等しい

# ifでもelifに当てはまらない場合はelse
a = 2
b = 1
if a < b:
    print('bの方が大きい')
elif a == b:
    print('aとbは等しい')
else:
    print('aの方が大きい')
# aの方が大きい

ifだけでの条件分岐も可能。この場合はifに当てはまらないと何も処理しない。

# ifだけでも使える(以下の場合は条件に当てはまらないので出力なし)
a = 2
b = 1
if a < b:
    print('bの方が大きい')

配列に要素があるかどうかで条件判定(in

条件文は何も大小関係だけではない。ありとあらゆる条件を使用することができる。ここでは配列中にある要素が存在しているか否かで条件判定をする。存在しない場合を判定する場合を判定するにはnotを使用する。

# 条件文は入れられる
lst = [1, 2, 3]
a = 1
b = 2
c = 4

if a in lst:
    print(f"{a}あり")
# 1あり

if c not in lst:
    print(f"{c}なし")
# 4なし

複数条件を設定する

単一の条件で判断するのではなく、複数の条件を適用することも可能。その時は以下で指定可能。

  • または: 条件 or 条件、もしくは、(条件) | (条件)
  • かつ: 条件 and 条件、もしくは、(条件) & (条件)
# 複数条件もあり
if a in lst or c in lst:
    print(f"{a}ありまたは{c}なし")
# 1ありまたは4なし
if (a in lst) | (c in lst):
    print(f"{a}ありまたは{c}なし")
# 1ありまたは4なし

if a in lst and b in lst:
    print(f"{a}ありかつ{b}なし")
# 1ありかつ2なし
if (a in lst) & (b in lst):
    print(f"{a}ありかつ{b}なし")
# 1ありかつ2なし

None, NaN, boolの判定(isnp.isnan

None(何もない)、NaN(Not a Number、非数値、データがなかったとか)、bool(真か偽、TrueFalse)を条件文で判定する際には注意点がある。

# NoneとNaNは判定が特殊
import numpy as np
a = None
b = np.nan
c = True
print(a, type(a))
# None <class 'NoneType'>
print(b, type(b))
# nan <class 'float'>
print(c, type(c))
# True <class 'bool'>

Noneの判定は==を使用しても可能だが、この場合はflake8というコードチェックに引っかかる。エラーではないが推奨されない書き方。エディタにコードチェック用のツールを導入している場合は、エディタ上で警告的なものが出る。

==ではなくisを使用するべし。

flake8とこれに関連するPEP8については以下の記事参照。

【PEP8&flake8】pythonにおけるPEP8とflake8

こんな人にオススメ pythonにつ{ ...

続きを見る

# None==でもエラーは出ないが、flake8の警告が出る(エディタ上で)
if a == None:
    print('aはNone')
# comparison to None should be 'if cond is None:'flake8(E711)
# aはNone

# is(同一性)で比較
if a is None:
    print('aはNone')
# aはNone

boolについても同様。なお、boolについては直で書いても既にboolなので条件判定に使用することができる。

# boolについてもエディタ上で警告が出る
if c == True:
    print('cはTrue')
# comparison to True should be 'if cond is True:' or 'if cond:'flake8(E712)
# cはTrue

if c is True:
    print('cはTrue')
# cはTrue

# boolについては直で書いていい
if c:
    print('cはTrue')
# cはTrue

NaNが一番特殊でこちらは==がそもそも効かない。isなら大丈夫だが、一番有名なのはnumpynp.isnan()。これはnanであるかどうかを判定してくれるもの。

import numpy as np
# NaNは==は効かない(この場合は出力なし)
if b == np.nan:
    print('bはNaN')

# isならいける
if b is np.nan:
    print('bはNaN')
# bはNaN

# もしくはnp.isnan
if np.isnan(b):
    print('bはNaN')
# bはNaN

NaNは四則演算すると結果がNaNになったり、pltでグラフが表示されなかったりと面倒なことが多いので使用には注意が必要。

for(繰り返し、反復)

データを1行ずつ読み込みたいなど、何か同じ操作を繰り返し行いたい場合はfor(繰り返し、反復)を使用する。pythonのforは他の言語に比べて処理が遅いので処理内容を工夫して処理が多くならないようにするのが賢明。

1重ループ

単純なループは以下。printすると1処理ごとに改行されていることがわかる。

# range(5)で0から5までを1刻みでデータ作成
for i in range(5):
    print(i)
# 0
# 1
# 2
# 3
# 4

# 上の例と同じ出力
# forの後の「j」は好きに変更可能(forとかrangeとかの予約後以外なら)
for j in range(0, 5, 1):
    print(j)
# 0
# 1
# 2
# 3
# 4

多重ループ

多重ループはネスト(インデントつけ)して記入する。pythonはこのインデントが厳しいのでインデントがいくつ入っているのかはしっかりと確認する必要がある。

また、多重ループでは先に書いたfor(以下ではi)が先に固定され、その固定の状態で後に書いたfor(以下ではj)のループが処理される。

# 多重ループでは先に書いた方を先に固定
for i in range(3):
    for j in range(10, 14):
        print(f"i={i}, j={j}")
    print('---')
# i=0, j=10
# i=0, j=11
# i=0, j=12
# i=0, j=13
# ---
# i=1, j=10
# i=1, j=11
# i=1, j=12
# i=1, j=13
# ---
# i=2, j=10
# i=2, j=11
# i=2, j=12
# i=2, j=13
# ---

配列をそのまま取り出し(listdict

上記ではrange関数を使用してforを作成したが、listなどの配列をそのままforに入れて処理することが可能。listtupleの場合は要素が、dictの場合はkeysが出力される。

# listなどをそのまま入れることも可能
lst = [10, 100, 1000]
for i in lst:
    print(i)
# 10
# 100
# 1000

# dictの場合はkeysが出力
dct = {'A': 1, 'B': 2, '': 3, 'C': 4}
for k in dct:
    print(k)
# A
# B

# C

dictvaluesが欲しい時は.values()にする。

# dictのvaluesが欲しい時は.values()にする
dct = {'A': 1, 'B': 2, '': 3, 'C': 4}
for v in dct.values():
    print(v)
# 1
# 2
# 3
# 4

keysの場合も同様に、.keys()と明示してもいい。

# keyが欲しい時に.keys()と明示してもいい
dct = {'A': 1, 'B': 2, '': 3, 'C': 4}
for k in dct.keys():
    print(k)
# A
# B
#
# C

.keys().values()()をつけてしまうとエラー。

# .valuesとカッコなしだとエラー
# for v in dct.values:
#     print(v)
#     for v in dct.values:
# TypeError: 'builtin_function_or_method' object is not iterable

# .keysも同様
# for k in dct.keys:
#     print(k)
#     for k in dct.keys:
# TypeError: 'builtin_function_or_method' object is not iterable

dictkeysvaluesも欲しい時は.items()keysvaluesの2つの値があるのでforの引数を2つにすると別々に取り出せる。

# keysもvaluesも欲しい時は.items()
for k, v in dct.items():
    print(f"key: {k}, value: {v}")
# key: A, value: 1
# key: B, value: 2
# key: , value: 3
# key: C, value: 4

引数を1つにするとtupleで取り出すことができる。

# forのループ変数を一つにするとtupleで出力
for kv in dct.items():
    print(f"key & value: {kv}, type(kv): {type(kv)}")
# key & value: ('A', 1), type(kv): <class 'tuple'>
# key & value: ('B', 2), type(kv): <class 'tuple'>
# key & value: ('', 3), type(kv): <class 'tuple'>
# key & value: ('C', 4), type(kv): <class 'tuple'>

複数の配列を同時forループ(zip

複数の配列を同時にforループする場合はzip関数が便利。forの引数は1つでもいいが、この時はtupleでまとめられる。

# 複数個の配列をループさせるならzip
lst1 = [0, 1, 2]
lst2 = [10, 20, 30]
for l1, l2 in zip(lst1, lst2):
    print(f"{l1}, {l2}")
# 0, 10
# 1, 20
# 2, 30

dictitemsを同時に取得したい場合は、それぞれのdictごとにカッコ()で分ける必要がある。

# 2つのdictのitemsを同時に取得したい時はそれぞれをカッコでくくる
dct1 = {'A': 1, 'B': 2, 'C': 3, }
dct2 = {'D': 10, 'E': 20, 'F': 30, }
for (k1, v1), (k2, v2) in zip(dct1.items(), dct2.items()):
    print(f"dct1: {k1} & {v1}, dtc2: {k2} & {v2}")
# dct1: A & 1, dtc2: D & 10
# dct1: B & 2, dtc2: E & 20
# dct1: C & 3, dtc2: F & 30

インデックスも同時取得(enumerate

forループで得られるデータが何番目のデータなのかなど、インデックスも同時に取得したい時はenumerateが便利。forのすぐ後にenumerateの引数を書く。また、enumerateの勘定始まりの数は0だが好きな値に変更可能。

# ループのインデックスを取得したいならenumerate
lst = [10, 100, 1000]
for num, i in enumerate(lst):
    print(f"No.{num}: {i}")
# No.0: 10
# No.1: 100
# No.2: 1000

# 好きな番号から始めるときは引数追加
lst = [10, 100, 1000]
for num, i in enumerate(lst, -1):
    print(f"No.{num}: {i}")
# No.-1: 10
# No.0: 100
# No.1: 1000

enumerateにはステップ数を指定する引数はない。したがって3ずつ記述など、1ではない場合は処理中に書く必要がある。

# ステップ数を表す引数はない
lst = [10, 100, 1000]
# for num, i in enumerate(lst, 1, 3):
#     print(f"No.{num}: {i}")
#     for num, i in enumerate(lst, 1, 3):
# TypeError: enumerate() takes at most 2 arguments (3 given)

# 出力時に調整すればOK
for num, i in enumerate(lst, 1):
    print(f"No.{num * 3}: {i}")
# No.3: 10
# No.6: 100
# No.9: 1000

zipenumerateを同時に回す

zipで複数のデータを回しつつenumerateでそのインデックスも取得したい場合は、enumeratezipの引数をカッコ()で分ける必要がある。

# enumerateとzipを併用する際には、zip部分をカッコでくくる
lst1 = [0, 1, 2]
lst2 = [10, 20, 30]
for num, (l1, l2) in enumerate(zip(lst1, lst2), 1):
    print(f"No.{num}: {l1}, {l2}")
# No.1: 0, 10
# No.2: 1, 20
# No.3: 2, 30

カッコしないとエラー。

# zip部分は別途カッコで括らないとエラー
# lst1 = [0, 1, 2]
# lst2 = [10, 20, 30]
# for num, l1, l2 in enumerate(zip(lst1, lst2), 1):
#     print(f"No.{num}: {l1}, {l2}")
#     for num, l1, l2 in enumerate(zip(lst1, lst2), 1):
# ValueError: not enough values to unpack (expected 3, got 2)

複数のdictkeysvaluesを取得しつつインデックスも取得したい場合は、enumeratezipを分けるカッコに加えてそれぞれのzipを分けるカッコも必要。

# 2つのdictのitemsを取得しつつ、インデックスも欲しい時は区別するカッコも必要
dct1 = {'A': 1, 'B': 2, 'C': 3, }
dct2 = {'D': 10, 'E': 20, 'F': 30, }
for num, ((k1, v1), (k2, v2)) in enumerate(zip(dct1.items(), dct2.items()), 1):
    print(f"No.{num}...dct1: {k1} & {v1}, dtc2: {k2} & {v2}")
# No.1...dct1: A & 1, dtc2: D & 10
# No.2...dct1: B & 2, dtc2: E & 20
# No.3...dct1: C & 3, dtc2: F & 30

forの中にifを入れる

forの中にifを入れて、反復処理をしながら条件分岐も可能。

# forにifを入れる
for i in range(10):
    if i < 7:
        if i % 2 == 0:  # 余りを計算
            print(f"{i}は7未満であり偶数")
        else:
            print(f"{i}は7未満であり奇数")
    else:
        print(f"{i}は7以上")
# 0は7未満であり偶数
# 1は7未満であり奇数
# 2は7未満であり偶数
# 3は7未満であり奇数
# 4は7未満であり偶数
# 5は7未満であり奇数
# 6は7未満であり偶数
# 7は7以上
# 8は7以上
# 9は7以上

内包表記(短縮版for

内包表記を使用すれば、for文を1行で書くことができる。処理が通常のfor文よりも速くなるものの、見づらかったりするので多用はいけない。他の部分で処理を早くするべし。

シンプルな内包表記

通常のforだと5行分のコードが、内包表記だと3行で済む。

# 内包表記
lst = [i for i in range(2, 5)]
print(lst)
# [2, 3, 4]

# 上記は以下と同等
lst = []
for i in range(2, 5):
    lst.append(i)
print(lst)
# [2, 3, 4]

多重ループの内包表記

多重ループの時は、内包表記内でカッコ[]を使用するか否かで処理が異なる。

まずは内包表記内にカッコがない場合。この場合は左側のforを先に固定し、右側のforを回す。

# 同時ループでは左側を固定して右側を回す
lst = [f"{i}{j}" for i in ('A', 'B', 'C') for j in [1, 2, 3]]
print(lst)
# ['A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3']

# 上記は以下と同等
lst = []
for i in ('A', 'B', 'C'):
    for j in [1, 2, 3]:
        lst.append(f"{i}{j}")
print(lst)
# ['A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3']

一方で内包表記内にカッコがあると多次元配列として扱うことになる。この場合は右側のforを先に固定し、左側のforを回すことになる。

# 左側のループをさらに[]でくくると、右側を先に固定
lst = [[f"{i}{j}" for i in ('A', 'B', 'C')] for j in [1, 2, 3]]
print(lst)
# [['A1', 'B1', 'C1'], ['A2', 'B2', 'C2'], ['A3', 'B3', 'C3']]

# 上記は以下と同等
lst = []
for j in [1, 2, 3]:
    lst_in = []
    for i in ('A', 'B', 'C'):
        lst_in.append(f"{i}{j}")
    lst.append(lst_in)
print(lst)
# [['A1', 'B1', 'C1'], ['A2', 'B2', 'C2'], ['A3', 'B3', 'C3']]

内包表記とif

内包表記内にifを使用することもできる。ifだけの場合は最後に書く。

# 内包表記でもifは使用可能
lst = [i for i in range(10) if i % 2 == 0]
print(lst)
# [0, 2, 4, 6, 8]

# 上記は以下と同等
lst = []
for i in range(10):
    if i % 2 == 0:
        lst.append(i)
print(lst)
# [0, 2, 4, 6, 8]

elseが入る場合はifelseを初めに書く。

# elseを入れたいときは先に書く(以下は偶数ならe、奇数ならoを初めにつける)
lst = [f"e{i}" if i % 2 == 0 else f"o{i}" for i in range(10)]
print(lst)
# ['e0', 'o1', 'e2', 'o3', 'e4', 'o5', 'e6', 'o7', 'e8', 'o9']

# 上記は以下と同等
lst = []
for i in range(10):
    if i % 2 == 0:
        ans = f"e{i}"
    else:
        ans = f"o{i}"
    lst.append(ans)
print(lst)
# ['e0', 'o1', 'e2', 'o3', 'e4', 'o5', 'e6', 'o7', 'e8', 'o9']

elifは使用できないので、3種類以上の条件を入れたい場合はelseの後に再度ifを書く必要がある。以下の例だと、偶数にはeをつけ、3の倍数は最後に!を、そしてそれ以外にはotherとつけている。

ただし、内包表記で書くとPEP8の79文字制限に違反しており、さらに内容も複雑になり可読性が低いの多用はしないほうがいいだろう。

PEP8については以下参照。

【PEP8&flake8】pythonにおけるPEP8とflake8

こんな人にオススメ pythonにつ{ ...

続きを見る

lst = [f"e{i}" if i % 2 == 0 else f"{i}!" if i % 3 == 0 else f"other{i}" for i in range(10)]
print(lst)
# ['e0', 'other1', 'e2', '3!', 'e4', 'other5', 'e6', 'other7', 'e8', '9!']

# 上記は以下と同等
lst = []
for i in range(10):
    if i % 2 == 0:
        ans = f"e{i}"
    elif i % 3 == 0:
        ans = f"{i}!"
    else:
        ans = f"other{i}"
    lst.append(ans)
print(lst)
# ['e0', 'other1', 'e2', '3!', 'e4', 'other5', 'e6', 'other7', 'e8', '9!']

関連記事

【python&独学】独学である程度pythonを習得するマインド

こんな人にオススメ pythonを新{ ...

続きを見る

【python&list】pythonのlistの超基礎

こんな人にオススメ pythonのlistっ& ...

続きを見る

e-typingのスコア軌跡
【Mac&タイピング】タッチタイピングで分間300打を超える方法

こんな人にオススメ タイピ ...

続きを見る

【VScode&拡張機能】python・C・LaTeX...ユーザーのVisual Studio Code拡張機能

こんな人にオススメ Visual Studio Codeと& ...

続きを見る

スイッチボット

2022/9/11

【SwitchBotロックレビュー】これからのスタンダードになりうるスマートロック

こんな人にオススメ SwitchBotからスマートロック「SwitchBotロック」が発売された ...

生活に役立つ

2022/10/25

【メガネ厳選】クソ便利に使っているサービスやアイテム達

このページでは執筆者「メガネ」が実際に使って便利だと感じているサ ...

マウス

2022/9/11

【Logicool MX ERGO vs MX Master 3】ERGOをメインにした決定的な理由

こんな疑問・お悩みを持っている人におすすめ 執筆者はLogicoolのハイエンӠ ...

完全ワイヤレスイヤホン(TWS)

2022/11/21

【ながら聴きイヤホン比較】SONY LinkBuds、ambie、BoCoはどれがおすすめ?

こんな人におすすめ 耳を塞がない開放型のイヤホンに完全ワイヤレスӟ ...

macOSアプリケーション

2022/10/15

【M1 Mac】MacBook Proに入れている便利でニッチなアプリを21個紹介する

こんな人におすすめ MacBookを購入してLINEとか必要最低限のアプリは入れた。 ...

完全ワイヤレスイヤホン(TWS)

2022/10/23

【SENNHEISER MOMENTUM True Wireless 3レビュー】高レベルでバランス型の高音質イヤホン

こんな人におすすめ SENNHEISER MOMENTUM True Wireless 3って実際のところどうなの? 評判は良い ...

完全ワイヤレスイヤホン(TWS)

2022/11/21

【SONY WF-1000XM4レビュー】神とゴミのハーフ&ハーフ

こんな人におすすめ SONYのフラグシップモデル「SONY WF-1000XM4」ってどれくらい性 ...

完全ワイヤレスイヤホン(TWS)

2022/8/19

【Nothing ear (1)レビュー】ライトな完成度、アップデートに期待

こんな人にオススメ 完全ワイヤレスイヤホン(TWS)でスケルトンボディ ...

Pythonを学びたいけど独学できる時間なんてない人へのすゝめ

執筆者は大学の研究室・大学院にて独学でPythonを習得した。

でも社会人になったら独学で行うには時間も体力もなくて大変だ。

時間がない社会人だからこそプロの教えを乞うのが効率的。

ここでは色んなタイプに合ったプログラミングスクールの紹介をする。

  • この記事を書いた人

メガネ

ベンチャー企業のWebエンジニア駆け出し。独学のPythonで天文学系の大学院を修了→新卒を1.5年で辞める→転職→今に至る。
常時金欠のガジェット好きでM1 MacBook Pro x Galaxy S22 Ultraの狂人。
人見知りで根暗だったけど、人生楽しもうと思って良い方向に狂う→人生が楽しい

ガジェットのレビューとPythonコードを記事にしています。ぜひ楽しんでください🦊
自己紹介と半生→変わって楽しいの繰り返し

-Python基礎
-,