本記事について
私自身がpython3について思い出したり、基本構文を参考にするためのメモです。
おまじない
# coding: utf-8
コメントアウト
# コメントアウトできます
'''
複数行のコメントアウトが可能
複数行のコメントアウトが可能
'''
# 数値
print(数値)
# 文字列
print("文字列")
# 改行しない
print(xxx, end="")
# 改行
print()
#********************************** f文字 **********************************
# 参考サイト:https://note.nkmk.me/python-f-strings/
# 記述方法 「123 and abc」と表示
# 「""」「''」どちらでもOK
num = 123
word = 'abc'
1. print('{} and {}'.format(a, b))
2. print('{first} and {second}'.format(first=a, second=b))
3. print(f'{a} and {b}')
# ゼロ埋め 「00001234」と表示
num = 1234
1. print(f'{num:08}')
2. print('{:08}'.format(num))
#***************** 2次元配列の中身をそのまま表示 *****************
## 例:list = [[0,1,2,3],[1,2,3,4],[2,3,4,5]]
#### 0123
#### 1234
#### 2345
for i in list:
print(*i, sep="")
# print(*i, sep=",") #sep=","とすると「,」区切りになる
変数
num = 10
word = "文字列"
# データ型を明示
num :int = 10
word :string = "文字列"
# 長さ
lenght :int= len(variable)
#***************************** 置換 *****************************
文字列.replace('置換対象の文字列', '置換後の文字列')
#***************** 文字列から特定の位置を取得 ※頭の文字は「0」*****************
word = "Hello, World!"
word[5] => ,
word[1:4] => ell
word[:4] => Hell
word[6:] => orld!
word[:] => Hello, World!
# 負の数で後ろから ※一番後ろは「-1」
word[-5] => o
word[-4:-1] => rld
データ型の判断
# 文字列が整数かどうか
文字列.isdigit()
## 1, 100, 11000 => True
## -10, 1.33, "alte" => False
メソッド(関数)
# 関数定義 ※頭文字は小文字がスタンダード
def func_name():
関数処理
# 関数の呼び出し
func_name()
#アノテーション(->)
#アノテーション:引数のデータ型を明示的にする
def func_name() -> 返り値の型名:
#***************** 引数のデフォルト *****************
## 例:argument2のデフォルトがtest
def func_name(argument1 = "test1", argument2 = "test2"):
func_name(argument2 = "testX") # argument2のみ指定
#*************** 可変長引数(リスト)=引数がリストとして長さが変化する ***************
## 例:argument2が可変長引数(リスト)
def func_name(argument1, *argument2):
func_name("test1", "list1", "list2", "list3")
#***************** 可変長引数(辞書)=引数が辞書として長さが変化する *****************
## 例:argumentが可変長引数(辞書)
def func_name(**argument):
func_name(name="名前", age=24, tall=175, hoby="映画")
クラス(class)
#***************** クラスの定義 ※頭文字は大文字 *****************
# クラス内の関数の引数に「self」を必ず入れる =>オブジェクトの情報を持つために必要
class ClassName:
variable = xx # クラス変数 = クラス内でのみ使用する変数
def func_name(self, argument):
関数処理
#***************** クラスからオブジェクト(インスタンス)を作成する *****************
# オブジェクト = 変数とメソッドをセットにした塊
object1 = ClassName()
object1.func_name("argument1")
#************************** コンストラクタ ***************************
# コンストラクタ = 初期実行 => 「__init__」メソッド
## self.*** = インスタンス変数 =>オブジェクトごとに持つインスタンス変数
class ClassName:
def __init__(self, argument):
self.argument = argument
def func_name(self):
print(self.argument)
object1 = ClassName("argument1")
object1.func_name()
object1.argument # クラス変数の呼び出し
#********************************** 継承 **********************************
## 例
## 親クラス(スーパークラス)= ParentClassName
## 子クラス(サブクラス)= ChildClassName
class ParentClassName:
def __init__(self, argument):
self.argument = argument
def parent_func_name(self):
class ChildClassName(ParentClassName): # 子クラスの引数に親クラス名を入れる
def child_func_name(self):
object = ChildClassName("argument")
object.child_func_name()
object.parent_func_name() #親クラスのメソッドも呼び出せる(クラス変数も維持)
#***************** クラス内の他のメソッドを実行 *****************
## クラス内から他のメソッドを実行=「self.method()」
class ParentClassName:
def parent_func_name(self):
self.__naibu()
def __naibu(self):
#***************** 子クラスで親クラスのメソッドを実行 *****************
## 親クラスのメソッドを実行=「super().method()」
class ChildClassName(ParentClassName):
def __init__(self):
super().__init__("argumentX")
#***************** プライベートメソッド(関数) *****************
## func_nameメソッドをプライベートメソッドにする = メソッド名の頭文字に「__」を付ける
## 外から呼び出し不可になる = クラス内でのみ使用するメソッド
class ClassName:
def __init__(self, argument):
self.argument = argument
def __func_name(self):
print(self.argument)
#***************** プライベート変数・プライベートプロパティ *****************
## argument変数をプライベート変数にする = 変数名の頭文字に「__」を付ける
class ClassName:
def __init__(self, argument):
self.__argument = argument
#************************** クラス変数 ***************************
## クラス変数: クラス自体が維持する変数 = オブジェクト生成されるたびに変数自体は維持される
### 例:クラス変数「__classvariable_count」はオブジェクト生成ごとに「+1」されていく
### ※クラス変数は、外部からいじられないようにプライベート変数(頭に__)に普通はする
class ClassName:
__classvariable_count = 0
def __init__(self, argument):
__classvariable_count += 1
#**************************** クラスメソッド ****************************
# クラスメソッド:オブジェクトからではなく、クラスから直接呼び出せる
# メソッドとクラスメソッドの呼び出しの違いの例 ↓
## メソッドの呼び出し => 1.object1 = ClassName("argument1") 2.object1.summary()
## クラスメソッドの呼び出し => 1.ClassName.summary()
class ParentClassName:
@classmethod
def summary(cls, argument): # 引数に「cls」を必ずつける
標準入力
# 文字の入力
word = input()
# 数値の入力
word = int(input())
# inputだと時間がかかるため、sys.stdinで高速に処理
import sys
for word in sys.stdin: print(word)
# 一行に複数の文字列を入力 => リスト化
# 入力値:amazon Microsoft Google
list = input().rstrip().split(" ")
## 配列ごと2次元配列に格納する
list.append(input().rstrip().split(" "))
# 一行に複数の数値を入力 => リスト化
## 入力値:23,55,333
list = [int(x) for x in input().rstrip().split(",")]
## 配列ごと数値で2次元配列に格納する
list.append([int(x) for x in input().rstrip().split(" ")])
# 2次元配列の入力 => リスト化
## 入力値 / 配列
## 1 2 3 / [[1,2,3],
## 4 5 6 / [4,5,6],
## 7 8 9 / [7,8,9]]
list = [input().split() for i in range(行数)]
# 不特定の行数の入力を配列に格納する
## 入力値
## My name is Mark.
## I am seven years old.
## Nice to meet you.
from sys import stdin
for line in stdin:
list = line.rstrip().split(' ')
繰り返し
#*********************** for文 ***********************
# 大前提
for 変数 in 条件:
処理内容
## 内包表記
[処理内容 for 変数 in 条件]
### 例:[i + j for i in range(10) for j in range(15)]
## 多重内包表記
[[処理内容 for 変数 in 条件] for 変数 in 条件]
### 例:list = [["0" for i in range(10)] for j in range(10)]
## 内包表記 + if文
[ifを満たしたときの内容 if if条件 else ifを満たさないときの内容 for 変数 in for条件]
### 例:list = ["even" if i % 2 == 0 else "add" for i in range(10)]
# x回繰り返す ※最初はi=0になる
for i in range(x):
# 多重forを一つにする
import itertools
for i, j in itertools.product(range(x), range(y)):
# 数値x-yまで増加させて繰り返す
for i in range(x,y):
for i in range(x,y,-1): # x > yで一ずつ減らしていく
# リスト(list)の要素を格納して繰り返す
for i in list:
#*********************** while文 *************************
while 条件式:
条件式が真の時に実行する文
配列(リスト)
# 定義
init_list = []
list = ["リスト1", "リスト2", "リスト3"]
#*********************** 要素内容を取得 ***********************
x = list[列番号]
# 2次元配列
list_2 = [[1, 2, 3], [10, 20, 30], [100, 200, 300]]
x = list_2[行番号][列番号]
##複数を同時に変数に代入
x, y, z = list_2[行番号]
#*********************** 入力値=>リスト化 ***********************
# 入力値:amazon Microsoft Google
word = input().rstrip().split(" ")
#*********************** 一行に複数の数値を入力=>リスト化 ***********************
# 入力値:23,55,333
list = [int(x) for x in input().rstrip().split(",")]
#*********************** 文字列を一文字=>リスト化 ***********************
word = "ABCDEFG"
word_list = list(word)
#*********************** リストに追加 ***********************
# リストの末尾に追加
list.append("文字列")
list.append(数値)
# リストの特定部分に追加
list.insert(配列番号, "文字列")
## list.insert(0, "XXX") #先頭に追加
#*********************** リストから削除 ***********************
## 特定の要素番号から削除
list.pop(配列番号)
### print(list.pop(0)) >> 「リスト1」が表示 + list[0]が削除
## 特定の要素内容から削除
del list(数値)
# *********************** リストで検索 ***********************
# リスト要素を検索
検索値 in list
# 戻り値はTrue or False
## 例:"リスト3" in list
# リスト要素の数を検索
list.count(検索値)
# リスト要素のindexを検索
list.index(検索値)
## ※検索値を複数持つリストの場合、一番小さいindexが取得可能
# 数値のリストから最大の要素を取得
max(list)
# 数値のリストから最小の要素を取得
min(list)
#*********************** リスト要素数に応じて繰り返す ***********************
for item in list:
print(item)
#*********************** ソート ***********************
# 普通のソート
print(sorted(list))
# 逆ソート
print(sorted(list, reverse=True))
#*********************** 配列の要素を要素番号を使用する:enumerate ***********************
## 例:list = ["apple", "Gooogle", "Microsoft"]
#### 0 apple
#### 1 Google
#### 2 Microsoft
for i, name in enumerate(list):
print(i, name)
辞書
# 定義
dictionary = {"キー1":"バリュー1(文字列)", "キー2":バリュー2(数値)}
# 辞書全部表示
print(dictionary)
# キーから特定バリューを表示
label="キー1"
print(dictionary[label])
# 辞書内容の更新
dictionary["キー2"] = バリュー2.1
# 辞書内容の削除
del dictonary["キー2"]
# for文との組み合わせ
for key in dictionary:
print(dictionary[key] + "です。")
for (key, value) in enemies.items():
print(key+ "の" + value+ "です。")
# ソート
print(sorted(dictionary )) # キーのみがリスト形式になってソートされる
print(sorted(dictionary .items())) # タプルになる。キーでソートされ、バリューもともに表示可能
#※タプル=内容の更新不可
例外処理
#******************** 例外処理フォーマット **********************
try:
実行する内容
except:
エラーの際に実行する内容
finally:
例外処理後に必ず実行する内容
#******************** エラーメッセージを表示する **********************
# 標準出力に表示する
import traceback
except:
print(traceback.format_exc())
# 標準エラー出力に表示する
import traceback, sys
except:
sys.stderr.write(traceback.format_exc())
#******************** 意図的に例外(エラー)を発生させる **********************
try:
raise BaseException("意図的な例外")
標準ライブラリ
math
import math
# log
math.log(x)
math.log(x, y)
# floor:小数点以下を切り捨て
math.floor(x)
# ceil:小数点以下を切り上げ
math.ceil(x)
# sqrt:平方根=√
math.sqrt(x)
# fabs:絶対値(正にする)
math.fabs(x)
# exp:eのx乗
math.exp(x)
# pow:xのy乗
math.pow(x, y)
=> 組み込み関数 pow(x, y)のほうがいい
datetime
datetimeモジュールで使用可能な4つのオブジェト
-
datetime.datetime
: 日時(日付と時刻) -
datetime.date
: 日付 -
datetime.time
: 時刻 -
datetime.timedelta
: 時間差・経過時間。datetimeオブジェクト同士を引き算すると取得できる。
メソッド2つ
-
strftime()
: 日付、時間 → 文字列への変換 -
strptime()
: 文字列 → 日付、時間への変換
参考サイト:https://note.nkmk.me/python-datetime-usage/
import datetime
#******************* datetimeオブジェクト(.datetime) *******************
## 現在の日時(.now())
dt_now = datetime.datetime.now()
## 属性 year, month, day, hour, minute, second, microsecond
dt_now.year
## 任意の日時作成 ↓コンストラクタ
datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None)
datetime.datetime(2021, 2, 1)
## dateオブジェトに変更
dt_now.date()
#********************* dateオブジェクト(.date) *********************
## 今日の日付(.today())
d_today = datetime.date.today()
## 属性 year, month, day
d_today.year
## 任意の日付作成 ↓コンストラクタ
date(year, month, day)
datetime.date(2021, 2, 1)
#*********************** timeオブジェクト(.time) ***********************
## 任意の時刻作成 ↓コンストラクタ
time(hour=0, minute=0, second=0, microsecond=0, tzinfo=None)
datetime.time(12, 15, 30, 2000)
## 属性 hour, minute, second, microsecond
t = datetime.time(12, 15, 30, 2000)
t.hour
#*********************** timedeltaオブジェクト(.timedelta)***********************
## 属性 days, seconds, microseconds
dt_now = datetime.datetime.now()
dt = datetime.datetime(2018, 2, 1, 12, 15, 30, 2000)
td = dt_now - dt
## 任意の時間差分を作成 ↓コンストラクタ
timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)
td_1w = datetime.timedelta(weeks=1) # 一週間
## timedeltaオブジェクトを使った引き算、足し算
### 例:1週間後を取得
datetime.date.today() + datetime.timedelta(weeks=1)
#******************* strftime(): 日付、時間 → 文字列への変換 *******************
## datetimeオブジェクトとdateオブジェクトのメソッド
dt_now = datetime.datetime.now()
dt_now.strftime('%Y-%m-%d %H:%M:%S')
#******************* strptime() : 文字列 → 日付、時間への変換 *******************
## datetimeオブジェクトのメソッド
date_str = '2021/2/1 12:30'
date_dt = datetime.datetime.strptime(date_str, '%Y/%m/%d %H:%M')
sys
Pythonのインタプリタや実行環境に関する情報を扱うことが可能になる
import sys
# 引数の使用
sys.argv[数値]
## 例:# sys.py hoge XXX
[print(sys.argv[x]) for x in range(len(sys.argv))]
### x=0 => sys.py / x=1 => hoge / x=2 => XXX
# 標準入力を高速にする
## input()だと時間がかかる
for word in sys.stdin:
# lines.append(word.rstrip('\r\n'))
# print(word)
# プログラム終了
sys.exit()
os
ファイル操作やコマンドラインでのシステム操作が可能
import os
# ファイルまたはディレクトリが存在するか判定
os.path.exists("パス")
## あればTrue、なければFaulse
# ファイルを開く
file = opne('パス', 'オプション')
## 【オプション】w:新規作成 a:上書き(なければ作成)
# ファイルへの書き込み(write)
file.write('書き込む内容\n')
## 配列を一括でファイルに書きこむ(writelines)
list = ['list1\n', 'list2\n', 'list3\n']
file.writelines(list)
# ファイルを閉じる
file.close()
numpy
import numpy as np
# 配列の定義
arr = np.array([1,2,3,4])
arr = np.array([x**2 for x in range(5)])
# 連続する同じ数値をグループ化する
arr = [0, 0, 0, 1, 1, 2, 0, 0]
print([(k, list(g)) for k, g in itertools.groupby(arr)])
## 出力結果: [(0, [0, 0, 0]), (1, [1, 1]), (2, [2]), (0, [0, 0])]
# 二次元配列全体で最大値の座標を取得(複数ある場合は最初の一つ)
arr = np.array([[1,2,3,4],[3,5,2,3],[1,2,5,3]])
idx = np.unravel_index(np.argmax(arr), arr.shape)
## print(idx) => (2, 1)
itertools
import itertools
# 連続する同じ数値をグループ化する
arr = [0, 0, 0, 1, 1, 2, 0, 0]
print([(k, list(g)) for k, g in itertools.groupby(arr)])
## 出力結果: [(0, [0, 0, 0]), (1, [1, 1]), (2, [2]), (0, [0, 0])]
その他
ランレングス圧縮
aaaabbcccddd
の文字列を圧縮してa4b2c3d3
とする。
下のコードでは配列表示されるようにしている。
LeetCode:https://leetcode.com/submissions/detail/742835849/
def rle(s):
tmp, count, ans = s[0], 1, []
for i in range(1,len(s)):
if tmp == s[i]:
count += 1
else:
ans.append([tmp,count])
tmp = s[i]
count = 1
ans.append([tmp,count])
return ans
word = "aaaabbcccddd"
print(rle(word))
>> [['a', 4], ['b', 2], ['c', 3], ['d', 3]]
# ※戻り値をa4b2c3d3をしたい場合は関数を以下部分で変更する
## ans = ""
## ans += tmp+str(count)
Manacherのアルゴリズム
極大回文を求めるアルゴリズムです。
文字列の各文字を中心とした回文の最長半径を求める。
一文字でも回分とみなすため、最小半径は1である
(例)aabbcccbbaa
の場合は、[1, 1, 1, 1, 1, 6, 1, 1, 1, 1, 1]
である。
LeetCode:https://leetcode.com/submissions/detail/744399492/
s = "aabbcccbbaa"
'''偶数の場合は文字列の間に「#」を入れて考える必要がある("a#a#b#b#c#c#c#b#b#a#a")
if len(s) % 2 == 0:
s_len = len(s)
for n in range(s_len):
if n < s_len-1:
s = s[:2*n+1] + "#" + s[2*n+1:]
'''
i, j = 0, 0
r = [ 0 for x in range(len(s)) ] # 極大回文の半径リスト
while i < len(s):
while i - j >= 0 and i + j < len(s) and s[i-j] == s[i+j]:
j += 1
r[i] = j
k = 1
while i - k >= 0 and k + r[i-k] < j:
r[i+k] = r[i-k]
k += 1
i += k
j -= k
print(r)
deque(デキュー)
≒ リスト形式で先頭・末尾についての操作のみをすることが可能です。
途中の部分を探したり、処理をするとリストより時間がかかってしまう
https://note.nkmk.me/python-collections-deque/
#**************** deque作成 deque([list1, list2]) ****************
deque_test = deque([1,2,3,4,5])
#*********************** 要素の取得 ***********************
print(deque_test [0])
>> 1
## マイナスで末尾からの数も可
#*********************** 要素の追加 ***********************
## 末尾に追加
deque_test.append(6) # deque([1,2,3,4,5,6])
## 先頭に追加
deque_test.appendleft(6) # deque([6,1,2,3,4,5])
## 末尾に複数要素追加
deque_test.extend([6,7]) # deque([1,2,3,4,5,6,7])
## 先頭に複数要素追加
deque_test.extendleft([6,7]) # deque([7,6,1,2,3,4,5])
## 中間に要素追加
deque_testinsert(3, 'XXX') # deque([1,2,3,'XXX'4,5])
#*********************** 要素の削除 ***********************
## 末尾に削除
deque_test.pop() # deque([1,2,3,4])
## 先頭に削除
deque_test.popleft() # deque([2,3,4,5])
## 特定の要素削除
deque_test.remove(2) # deque([1,3,4,5])
## 全要素削除
deque_test.remove() # deque([])
#*********************** 要素のローテート ***********************
# 末尾を先頭にローテート
deque_test.rotate() # deque([5,1,2,3,4])
## .rotate(x) => xの数だけローテートすることが可能
# 先頭を末尾にローテート
deque_test.rotate(-x) # deque([2,3,4,5,1])
## .rotate(-x) => xの数だけローテートすることが可能
参考リンク