diadia

興味があることをやってみる。自分のメモを残しておきます。

dictの値にリストを使うときの注意点

dict[key] = dict[key].append("要素")の結果はNone

dict型データの値にリストを設ける。そして必要な情報をリストに格納しようと思い以下のコードを書いた。

sample = dict(column1=[])

key = [key for key in sample.keys()][0]
print(key)
#1 column1

value = [value for value in sample.values()][0]
print(value)
#2 []
print(type(value))
#3 <class 'list'>

'''疑問:valueの[]に要素を加えることができるか?検証する'''

print("入れる前 : ",sample[key])
#4 入れる前 :  []
sample[key] = value.append("要素1") 

print("入れた後 : ",sample[key])
#5 入れた後 :  None
print(sample)
#6 {'column1': None}

ここで注目すべきは、dictの値としてリストを設け、そのリストにappendを使うと値はNoneになってしまうことだ。期待していたことは{'column1': "要素1"}となることだったのに。。。

期待の結果を得る方法

上記では期待の結果が得られなかったのはappendに問題があるようだ。appendメソッドを実行せずにリストにリストを加えるとdictにリストの要素を加えることができる。

my_list = [1,2,3] 
test_list = [4,5]
my_list + test_list
# [1, 2, 3, 4, 5]
""" リスト同士の+は結果としてappendの形になる。解決にこれを利用する """
test_list = [1]
sample = dict(column1=[])

sample[key] = sample[key] + ["新たな要素"] 

print("入れた後 : ",sample[key])
# 入れた後 :  ['新たな要素']
print(sample)
# {'column1': ['新たな要素']}

appendについて補足情報

https://codeday.me/jp/qa/20190205/212233.html
append()は破壊的な操作であるらしく、非破壊的な操作は + であるらしい。
https://stackoverflow.com/questions/1682567/why-does-list-append-evaluate-to-false-in-a-boolean-context

Most Python methods that mutate a container in-place return None -- an application of the principle of Command-query separation. (Python's always reasonably pragmatic about things, so a few mutators do return a usable value when getting it otherwise would be expensive or a mess -- the pop method is a good example of this pragmatism -- but those are definitely the exception, not the rule, and there's no reason to make append an exception).

コンテナをその場で変更するほとんどのPythonメソッドはNoneを返します。これは、コマンドとクエリの分離の原則を適用したものです。みたいなことが書いてあり、リストの中身を変えるメソッドを使うと、Noneが返されるのが一般的らしい。これはappendに限らず、remove()も同様の結果になる。

my_list = [1,2,3,4,5]
print(my_list.append(6))
# None
r = my_list.append(7)
print(r)
# None

print(my_list.remove(1))
# None
r = my_list.remove(2)
print(r)
# None