JavaScriptエンジニアがPythonを学ぶ(型定義とか)
JavaScriptとPythonの記述方法の違いだったり便利機能をまとめる
文字列
テンプレートリテラル
js
const test = `hello
world`
Python
test = """hello
world"""
Pythonは「"""」で囲みになり見にくいので、下記のようにして記載してもいい
test = """\
hello
world\
"""
出力結果
hello
world
単純に文字列連結して出力するだけなら下記でも可
test = (
'hello'
'world'
)
出力結果
helloworld
エスケープテクニック
基本的には \ があるとエスケープされるのはどちらも同じ
ただpythonは r を先頭につけると \ があってもエスケープされなくなる
(rはrawから来ている)
print('1 C:\name\test')
print(r'2 C:\name\test')
出力結果
1 C:
ame est
2 C:\name\test
コメントアウト
jsのコメントアウトは基本的には下記の認識
js
// 一行コメント
/*
複数行まとめてコメント1
複数行まとめてコメント2
*/
python
# 一行コメント
"""
複数行まとめてコメント1
複数行まとめてコメント2
"""
スライス(配列やタプルでも使える)
jsの文字列のスライスは基本的にscliceメソッドを噛ませる必要がある・・・はず
js
const test = 'hello world'
console.log(test.slice(0,5))
Pythonではコロンを使って表すスライスという機能があるのでこれを使用すると文字列やリスト操作が楽になる
Python
test = 'hello world'
print(test[0:5])
出力結果
hello
最初から◯文字までや、◯文字目から最後までや全件表示なら以下のような記載方法
test = 'hello world'
print(test[:5])
print(test[6:])
print(test[:])
出力結果
hello
world
hello world
これを利用するとjsの分割代入チックなことができる(参照切りたいときに使える)
js
const test = [1,2,3,4,5]
const [a, ...arg] = test
console.log([100,...arg])
Python
※ * は配列のアンパック
test = [1,2,3,4,5]
print([100,*test[1:]])
出力結果
[100, 2, 3, 4, 5]
文字列の代入
jsはテンプレートリテラルを使って書くのが今は一般的
const a = 'hello'
const b = 'world'
console.log(`${a} ${b}!`)
Python3.6よりformatじゃなく、f-stringsが使えるようになったのでそちらを使う
(fを先頭につける)
a = 'hello'
b = 'world'
print(f'{a} {b}!')
出力結果
hello world!
従来のformat形式は下記
# 変数名あり
print('{a} {b}!'.format(a='hello', b='world'))
# 変数名なし
print('{0} {1}!'.format('hello', 'world'))
リスト
スライスに第三引数を指定
スライス機能は第三引数(step)を設定することができる
これを設定すると設定数分飛び飛びで配列を取得できる
また、マイナス値を設定すると逆順で取得できる
n = [1,2,3,4,5,6,7,8,9,10]
print(n[::2])
print(n[::-1])
出力結果
[1, 3, 5, 7, 9]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
スライスを使った代入
スライス機能を使うと任意の値に代入することができる
この時代入する値は同じ数用意する(今回は2~5なので3つ分)
n = [1,2,3,4,5,6,7,8,9,10]
n[2:5] = [100,200,300]
print(n)
出力結果
[1, 2, 100, 200, 300, 6, 7, 8, 9, 10]
また空配列を代入すると対象の値を消すことができる
n = [1,2,3,4,5,6,7,8,9,10]
print(n)
n[2:5] = []
print(n)
n[:] = []
print(n)
出力結果
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 6, 7, 8, 9, 10]
[]
リストの連結
jsは・・・自分なら分割代入を使う
(普通同じ変数は使い回さないけど)
let a = [1,3]
const b = [2,4]
a.push(...b)
console.log(a)
Pythonは+=で連結ができる
a= [1,3]
b= [2,4]
a += b
# extendでも可
# a.extend(b)
print(a)
出力結果
[1, 3, 2, 4]
リストのコピー
jsもPythonも配列をそのまま代入すると参照渡しになるので、copyやdeepcopyを使って参照渡しを回避する(もちろん後述の辞書型でも起こるので気をつける)
js
// シャローコピー
const copy = [1,2,3,4,5]
const tmp = [...copy]
copy[0] = 100
console.log(copy,tmp)
// ディープコピー
const deep = [[1,2,3,4,5],[6,7,8,9,10]]
const tmp2 = structuredClone(deep)
deep[0][0] = 100
console.log(deep)
console.log(tmp2)
Python
# シャローコピー
copy = [1,2,3,4,5]
tmp = copy.copy()
copy[0] = 100
print(copy,tmp)
# ディープコピー
import copy
deep = [[1,2,3,4,5],[6,7,8,9,10]]
tmp2 = copy.deepcopy(deep)
deep[0][0] = 100
print(deep)
print(tmp2)
出力結果
//シャローコピー側
[100, 2, 3, 4, 5] [1, 2, 3, 4, 5]
//ディープコピー側
[[100, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
タプル
配列に似ているが、配列で使えるメソッドがなかったりや再代入、値の代入などができない
書き換えたくない元データなんかで使うと良さげ
使用できるメソッド
index
count
また配列の参照などはできる
jsにはない機能なのでjs側は省略
定義方法
numbers = (1,2,3,4,5,6,7,8,9,10)
ただ多次元でタプル内が配列だと書き換えできる
numbers = ([1,2,3,4,5],[6,7,8,9,10])
# Error
# numbers[0] = [100,200,300]
# タプルの中身を変更する
numbers[0][0] = 100
print(numbers)
出力結果
([100, 2, 3, 4, 5], [6, 7, 8, 9, 10])
また、カッコ無しカンマ区切りでも定義できる
numbers = 1,2,3,4,5,6,7,8,9,10
この記載方法ができるのでバグの原因にもなり得るので注意
例
number = 1
print(type(number))
number = 1,
print(type(number))
出力結果
<class 'int'>
<class 'tuple'>
カッコで定義した時も1つの場合は挙動の変化に注意する
number = (1)
print(type(number))
number = (1,)
print(type(number))
出力結果
<class 'int'>
<class 'tuple'>
タプルとタプルの連結
再代入はできないがタプル同士の連結はできる
(型がタプル以外の場合は不可)
a = (1,2,3,4,5)
b = (6,7,8,9,10)
c = a + b
print(c)
出力結果
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
タプルのアンパッキング
jsの分割代入的なもの
下記の様な記載をすると分割して変数に代入できる
a = (1,2)
x,y = a
print(x)
print(y)
出力結果
1
2
応用
変数の値を入れ替えたいときに応用が効く
普通はtmpのような別の変数を経由して上げる必要があるが不要になる
# 従来
a = 1
b = 2
tmp = a
a = b
b = tmp
# 応用の書き方
a = 1
b = 2
a,b = b,a
print(a)
print(b)
出力結果
2
1
辞書型
jsのObject型
const num = {a:1,b:2,c:3}
console.log(num)
pythonの場合はkey名を文字列定義してあげないとエラーになる
num = {'a':1,'b':2,'c':3}
print(num)
# 参照も同じ感じで定義する
# num['a']
出力結果
# js
{a: 1, b: 2, c: 3}
# py
{'a': 1, 'b': 2, 'c': 3}
辞書型いろいろな定義方法
下記のような記載方法でも辞書型を生成できる
# 辞書型はtype的にはdict
num1 = dict(a=1, b=2, c=3)
print(num1)
# タプルを使って定義
num2 = dict([('a', 1), ('b', 2), ('c', 3)])
print(num2)
出力結果
{'a': 1, 'b': 2, 'c': 3}
{'a': 1, 'b': 2, 'c': 3}
存在しない値を参照した場合
辞書型で存在しないkeyを参照した場合はどうなるか
jsはundefinedが返ってくる
const num = {a:1}
console.log(num.b)
console.log(typeof num.b)
出力結果
undefined
undefined
pythonはNoneTypeという型が返ってくる
(参照しただけだとprintしても空になるのでtype関数を使って確認する)
num = {'a':1}
#下記参照方法はエラーになるのでgetを使う
# print(num['b'])
b = num.get('b')
#printは出力されない
print(b)
type(b)
出力結果
None
集合型
重複した値の入力を防げる型
多分jsにはない(おそらく)
記載方法は {} を使う
num = {1,2,2,3,4}
animal={'dog','cat','bird','dog'}
print(num)
print(animal)
出力結果を見た感じ最後に出てきたほうが優先されそう
出力結果
{1, 2, 3, 4}
{'bird', 'cat', 'dog'}
また、2種類の集合を引くと左辺から右辺で重複したものを削除できる
(元順番は担保されなそう?)
num1 = {2,4,6,8}
num2 = {3,6,9,12}
# 重複削除
print(num1 - num2)
出力結果
{8, 2, 4}
その他
右辺と左辺どちらにも存在する値を出力したい場合は &
右辺と左辺を結合したい場合は |
右辺か左辺に存在する値を抽出したい場合は^
を使用する
num1 = {2,4,6,8,10,12}
num2 = {3,6,9,12}
print(num1 & num2)
print(num1 | num2)
print(num1 ^ num2)
出力結果
{12, 6}
{2, 3, 4, 6, 8, 9, 10, 12}
{2, 3, 4, 8, 9, 10}
配列から重複を削除する
pythonには集合という型があるので、配列内の重複しているものに関しては
配列型から集合型へ変換してあげると重複の削除ができる
animals = ['dog','bird', 'cat', 'dog']
# 集合型はtypeを見るとclass 'set'と返ってくる
kind = set(animals)
print(kind)
print(type(kind))
出力結果
{'bird', 'cat', 'dog'}
<class 'set'>
range型
引数で指定した数の連続した数値を持つ型
引数は下記のように指定できる
range(stop)
range(start,stop[,step])
以下のように指定すると 0 ~ 9までの連続した数値を扱うことができる
range(10)
for文とかで使うと良さそう
for i in range(10):
print(i)
stepを書くと以下のような出力結果になる
for i in range(0,10,2):
print(i)
出力結果
0
2
4
6
8
型だったり何かしらの機能を確認する(help)
pythonはhelp関数を使うとメソッドの使い方何かを表示してくれるので困ったことがあれば一旦
help関数を呼び出してあげると良さそう
"""
上から順に
リスト型
タプル型
辞書型
集合型
のhelpを呼び出す記述
"""
help(list)
help(tuple)
help(dict)
help(set)
型を調べる(type)
型を調べたい場合は、
type関数を使う
a = "1"
print(type(a))
出力結果
<class 'str'>
これ系のリンク
JavaScriptエンジニアがPythonを学ぶ(型定義とか)(ここ)
JavaScriptエンジニアがPythonを学ぶ(◯◯文とかエラー処理)
Discussion