Python3.7でtuple、namedtuple、list、dict、自作オブジェクトのforループ

ループさせる方法が型によって微妙に違うので、tuple、namedtuple、list、dict、自作オブジェクトのループの仕方をまとめた。

tuple

tupleの値をループする

そのままfor 変数 in タプルとすればループできる。

tpl = ('hoge', 'fuga', 'piyo')
for t in tpl:
    print(t)

実行結果

hoge
fuga
piyo

tupleの値をインデックス付きでループする

enumerate関数でインデックス付きにしてループする。

tpl = ('hoge', 'fuga', 'piyo')
for index, t in enumerate(tpl):
    print(index, t)

実行結果

0 hoge
1 fuga
2 piyo

dict

dictのプロパティ名をループする

そのままfor 変数 in 辞書とすると、プロパティ名だけループされる。

dic = {'name': 'aya', 'age': 20, 'score': 56}
for d in dic:
    print(d)

実行結果

name
age
score

dictの値をループする

values()メソッドで値の一覧をループすることができる。

dic = {'name': 'aya', 'age': 20, 'score': 56}
for d in dic.values():
    print(d)

実行結果

aya
20
56

dictのプロパティ名と値をループする

プロパティ名とともに値も一緒にループしたい場合、items()メソッドを使ってループする。

dic = {'name': 'aya', 'age': 20, 'score': 56}
for name, value in dic.items():
    print(name, value)

実行結果

name aya
age 20
score 56

dictのプロパティ名をインデックス付きでループする

dictitems()メソッドによりプロパティ名と値の一覧を取得した上で、enumerate関数によりインデックスをつけてループする。

dic = {'name': 'aya', 'age': 20, 'score': 56}
for index, (name, value) in enumerate(dic.items()):
    print(index, name, value)

実行結果

0 name aya
1 age 20
2 score 56

namedtupleで生成したオブジェクトのプロパティと値をループする

namedtupleで生成したオブジェクトのプロパティと値をforでループするには、_asdict()メソッドでcollections.OrderedDictに変換したうえで、items()メソッドによりプロパティ名と値を取得する。
なお、dictの取得は自作のオブジェクトと違いvars()関数がvars() argument must have __dict__ attributeとエラーになり使えない。

from collections import namedtuple

Person = namedtuple('Person', 'name age score')
nancy = Person('nancy', 18, 89)
or name, value in nancy._asdict().items():
    print(name, value)

実行結果

name nancy
age 18
score 89

自作のオブジェクトのプロパティと値をループする

vars()関数でdictに変換してからitemsメソッドでループする。

class Todo:
    def __init__(self, name:str, done:bool):
      self.name = name
      self.done = done

t = Todo('牛乳を買う', False)

for name, value in vars(t).items():
    print(name, value)

実行結果

name 牛乳を買う
done False

list

オブジェクトのlistをループする

そのままfor 変数 in リストとすればループできる。

class Todo:
    def __init__(self, name:str, done:bool):
      self.name = name
      self.done = done

todos = [Todo('牛乳を買う', False), Todo('洗濯をする', True), Todo('ご飯をつくる', False)]

for t in todos:
  print(t.name, t.done)

実行結果

牛乳を買う False
洗濯をする True
ご飯をつくる False

オブジェクトのlistをインデックス付きでループする

enumerate関数でインデックス付きにしてループする。

class Todo:
    def __init__(self, name:str, done:bool):
      self.name = name
      self.done = done

todos = [Todo('牛乳を買う', False), Todo('洗濯をする', True), Todo('ご飯をつくる', False)]

for index, t in enumerate(todos):
  print(index, t.name, t.done)

まとめ

  • tupleとlistは何も考えずにfor 変数 in tupleかlistでループできる
  • dictはそのままループするとプロパティ名のみ、valuesメソッドで値のみ、itemsメソッドでプロパティと値をループできる
  • index付きでループしたい場合はenumerate関数を使う
  • namedtupleは_asdictメソッドでdictに変換してループする
  • 自作のオブジェクトはvars関数でdictに変換してループする

参考

https://stackoverflow.com/questions/33984333/looping-over-elements-of-named-tuple-in-python

https://stackoverflow.com/questions/36244380/enumerate-for-dictionary-in-python