Pythonのユースケースと便利な書き方やライブラリをまとめる

配列同士の組み合わせを作成する
以下のような組み合わせを作りたい。
最初はzipでやることも考えたが要素数が異なると困る?のではと思って便利なやり方がないか調べたところitertools を使えば簡単に実現できそうだった。
sample1 = [1, 2]
sample2 = [3, 4]
>> [(1, 3), (1, 4), (2, 3), (2, 4)]
実現方法
itertoolsのproduct
を使う。
import itertools
sample1 = [1, 2]
sample2 = [3, 4]
list(itertools.product(sample1, sample2)) # [(1, 3), (1, 4), (2, 3), (2, 4)]
itertoolsには他にも便利な機能がありそう。

三項演算子(if文を短くかく)
# 三項演算子のパターン
status = ['SoldOut'] if 'sold-out' in classes else []
# 単純なifを1行でかく
if item.select('.sold-out'): status.append('SoldOut')
参考資料

辞書のリストを検索する

配列で重複していない要素を求める
a = [1, 2, 3]
b = [1, 2, 3, 4, 5]
set(b)^set(a) # {4, 5}

JSON
JSONファイルの出力・書き出し
ファイルへの書き出し
json.dump
を使う。
オプション等は基本的にjson.dumps
と同様
import json
with open('sample.json', 'w') as f:
json.dump(texts, f, indent=4, ensure_ascii=False)
json.dumpsで対応していない型をJSON文字列に変換する
日付(datetime)などはJSONの型として定義されていないため、json.dumpsで変換しようとすると以下のようなエラーが出てしまう。
TypeError: Object of type 'datetime' is not JSON serializable
参考資料にあるように、変換方法を定義して、json.dumpsの際にそれを使うよう指定すれば変換が行える。
書き出したファイルの読み込み
json.loads
を使って読み込んだものをDictionaryに変換すればいい。
with open('sample.json',) as f:
scrap_data = json.loads(f.read())
参考資料

日付関係の処理
datetimeオブジェクト
datetime.nowで現在の日付を取得できる。
import datetime
# now()で現在時刻を取得できる
now = datetime.datetime.now()
now # datetime.datetime(2021, 10, 30, 17, 26, 24, 530596)
# datetimeオブジェクトはmonthやyearなどのプロパティにアクセスできる
print(now.year) # 2021
print(now.month) # 10
print(now.day) # 30
文字列への変換
datetimeオブジェクト.strptime
で文字列に変換できる。
now.strftime('%Y/%m/%d')
文字列から日付型への変換
strftime
で文字列から日付型への変換ができる。
str_now = now.strftime('%Y/%m/%d')
datetime.datetime.strptime(str_now, "%Y/%m/%d") # datetime.datetime(2021, 10, 30, 0, 0)
ISOフォーマットの取り扱い
.isoformat
でISOフォーマットの文字列に変換できる。
# datetimeを文字列に変換
now.isoformat() # 2021-10-30T17:26:24.530596
文字列→日付型の変換はfromisoformat
でできるはずだが、isoformat
で変換した文字列が変換できない...
datetime.date.fromisoformat(now.isoformat()) # ValueError: Invalid isoformat string: '2021-10-30T17:13:07.087418'
dateutil.parser
を使えばdatetimeとして読み込める。
import dateutil.parser
dateutil.parser.parse(now.isoformat()) # datetime.datetime(2021, 10, 30, 17, 26, 24, 530596)
AirtableのAPIから取得したZが含まれるISOフォーマットでも問題なく読み込める。
test_data = res.json()
test_data['records'][14]['fields']["Date"] # 2021-10-30T16:04:07.432Z
dateutil.parser.parse(test_data['records'][14]['fields']["Date"]) # datetime.datetime(2021, 10, 30, 16, 4, 7, 432000, tzinfo=tzlocal())
参考資料
前月を取得する
以下のコードで前月が取得できる
# ライブラリのインポート
import datetime
# 今日を取得
today = datetime.datetime.today()
print(today.strftime("%Y-%m-%d"))
# 当月1日の値を出す
thismonth = datetime.datetime(today.year, today.month, 1)
print(thismonth.strftime("%Y-%m-%d"))
# 前月末日の値を出す
lastmonth = thismonth + datetime.timedelta(days=-1)
print(lastmonth)
# フォーマットを指定して、年月だけ拾う
print(lastmonth.strftime("%Y%m"))
以下の資料をそのまま使っただけ。

複数ファイルの連結
- 複数のファイルを連結したいケース。
具体的な使用例として自然言語処理のデータセットでデータセットが個別のテキストファイルに分かれているケースでの連結に使用
import glob
read_files = glob.glob("*.txt")
with open("result.txt", "wb") as outfile:
for f in read_files:
with open(f, "rb") as infile:
outfile.write(infile.read())
python - Pythonを使用して複数のテキストファイルを1つのテキストファイルに結合する[複製] - ITツールウェブ

ソート
-
ソートする
- 特定の項目でソートする
- JSONをソート
-
リストを逆順にする
- 特定の項目でのソートではなく、単純に順番を逆にする方法。
ユースケースとして、APIの返りが新しいレコード順の場合に古い順に変更するなど - 選択肢
-
reverse
- 元のリストの内容を変更する破壊的な関数
-
- 特定の項目でのソートではなく、単純に順番を逆にする方法。
org_list = [1, 2, 3, 4, 5]
org_list.reverse()
print(org_list)
# [5, 4, 3, 2, 1]```
- `reversed`
- 元のリストの内容は変更せず、イテレータを返す非破壊的な関数
- スライス
- スライスを活用しても同様のことが実現できる
- ```python
org_list = [1, 2, 3, 4, 5]
new_list = org_list[::-1]
print(org_list)
print(new_list)
# [1, 2, 3, 4, 5]
# [5, 4, 3, 2, 1]```
- コード
- ```python
sorted_tweet_list = reversed(search_tweets)
sorted_tweet_list # <list_reverseiterator at 0x10c9b1c70>

URLやクエリパラメータの扱い
Pythonの標準ライブラリであるurllib はリクエストを送信したり、URLをパースするための便利な機能を提供している。
URLの連結
urllib.parse
のurljoin
を使うことで、ドメインと相対URLから絶対URLを簡単に生成することができる。
具体的なユースケースとしてはスクレイピングでaタグのhrefから相対URLを取得した後、対象ページのURLと組み合わせることで次のスクレイピング対象のページを絶対URLで取得する場合など。
import urllib.parse
base_url = 'https://www.example.com'
relative_url = '/sample/test'
urllib.parse.urljoin(base_url, relative_url) # https://www.example.com/sample/test
base_url = 'https://www.example.com/'
relative_url = '/sample/test'
urllib.parse.urljoin(base_url, relative_url) # https://www.example.com/sample/test
クエリパラメータ
クエリパラメータを含んだURLからクエリパラメータの部分を抜き出して中身を変えたり、Dictionaryからクエリパラメータを生成したりすることができる。
-
parse_qs
- URLの文字列を渡すことでクエリパラメータを抜き出してくれる
-
urlencode
- Dictionaryを渡すことでクエリパラメータを文字列に変換してくれる
参考資料

文字列関係
基本文法
文字列が含まれているか確認する
文字列の中に任意の文字列が含まれているか判定・確認するにはin演算子を使う。含まれているとTrue、含まれていないとFalseを返す。
記号を削除する
- Pythonの正規表現で特殊記号をすべて闇に葬り去りたいとき - Qiita
- Python 半角の記号を削除したい - Qiita
- Python で文字列から特殊文字を削除する | Delft スタック
空白を取り除く
replaceを使うと色々な方法があるが、まとめて余計なものを消したいなら以下の正規表現を使うのが簡潔でわかりやすい気がする。
import re
#改行、タブ、スペースなどをまとめて削除
text = "a\u3000\n\n b\t\nc\r\nd\x0ce\x0b\rf\r\n"
text = re.sub(r"\s", "", text)
#改行コード(\r\nや\n)だけをまとめて削除
text = "a\u3000\n\n b\t\nc\r\nd\x0ce\x0b\rf\r\n"
text = re.sub(r"[\r\n]", "", text)
#いくつかのスペース(例えば全角スペース、半角スペース、タブ)をまとめて削除
text = "a\u3000\n\n b\t\nc\r\nd\x0ce\x0b\rf\r\n"
text = re.sub(r"[\u3000 \t]", "", text)
参考資料
正規表現
数字だけを残す
カンマや¥など余計ば文字列を省いて数字だけを抽出する方法。
content = '¥2,640 税込'
pattern = '[^0-9\n]|^\n'
result = re.sub(pattern, "", content)
print(result) # 2640
content = '¥2,640 税込'
pattern = '\D'
result = re.sub(pattern, "", content)
print(result)

Listの扱い
配列同士を比較
- 並びも含めて同一性を確認したい場合
- Listのまま
==
で比較
- Listのまま
- 要素が含まれているかだけ確認したい場合
- setに変換して比較
Dictionaryの配列を結合
data = [
{'name' : 'John'}
]
data1 = [
{'name' : 'Tom'}
]
print(data + data1) # [{'name': 'John'}, {'name': 'Tom'}]
print(data.extend(data1)) None

環境変数の活用
python-dotenv
をインストールした上でload_dotenv
を実行すれば.env
ファイルの内容にアクセスできるようになる。
TEST_DATA=aaaaa
import os
from dotenv import load_dotenv
# .envファイルの内容を読み込む
load_dotenv()
print(os.environ.get('TEST_DATA')) # aaaaa

ファイルへの書き出し
基本的にpandasが入れられる環境ならpandasからやるのがコード的には一番簡単な気がする。
参考資料

Collection Types
Dataclass
dataclasses.asdict
を使うことでdictionaryとして出力できる。
dataclasses.asdict

Dictionaryを検索
アプローチとして以下の3つ?
- リスト内包表記
- filterの利用
list(filter(lambda item: item['url'] in newly_added_urls, all_pages))
特定のキーを元にソート
sorted(l, key=lambda x: x.get('Point', 75))
参考資料

小数点以下の桁数を指定
fプリフィクスを使う方法がベター。
num = 123456.789
print(f'{num:,}') #位取り
print(f'{num:.3g}') #3桁まで表示
print(f'{num:.1f}') #小数点以下1位まで表示
print(f'{num:.2e}') #小数点以下2位までの指数で表示

基本演算
合計を出力
組み込み関数のSumを使うのがいい。
myList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
listSum = sum(myList)
print(f"Sum of list -> {listSum}")
