🐍

PHPの多次元配列と、Pythonの辞書リストを比較する

2022/02/03に公開約4,000字

この手の配列はRDBテーブルからデータ取得後に配列変換されよく見かける形です。
縦(列)と横(行)の関係性で考えると難しくなくなります。

booksテーブル

作者 タイトル 出版年
Franz Kafka The Metamorphosis 1915
Ernest Hemingway The Sun Also Rises 1926
J. R. R. Tolkien The Hobbit 1937

定義記法

連想配列(辞書)が連続して一つの配列(リスト)を作っているイメージです。

PHP
$books = array(
    ['author' => 'Franz Kafka', 'title' => 'The Metamorphosis', 'year' => 1915],
    ['author' => 'Franz Kafka', 'title' => 'The Castle', 'year' => 1926],
    ['author' => 'Ernest Hemingway', 'title' => 'The Sun Also Rises', 'year' => 1926],
    ['author' => 'Ernest Hemingway', 'title' => 'The Snows of Kilimanjaro', 'year' => 1940],
    ['author' => 'Ernest Hemingway', 'title' => 'The Old Man and the Sea', 'year' => 1952],
    ['author' => 'J. R. R. Tolkien', 'title' => 'The Hobbit', 'year' => 1937],
    ['author' => 'J. R. R. Tolkien', 'title' => 'The Fellowship of the Ring', 'year' => 1954],
    ['author' => 'J. R. R. Tolkien', 'title' => 'The Two Towers', 'year' => 1954],
    ['author' => 'J. R. R. Tolkien', 'title' => 'The Return of the King', 'year' => 1955],
);
Python
books = [
    {'author': 'Franz Kafka', 'title': 'The Metamorphosis', 'year': 1915},
    {'author': 'Franz Kafka', 'title': 'The Castle', 'year': 1926},
    {'author': 'Ernest Hemingway', 'title': 'The Sun Also Rises', 'year': 1926},
    {'author': 'Ernest Hemingway', 'title': 'The Snows of Kilimanjaro', 'year': 1940},
    {'author': 'Ernest Hemingway', 'title': 'The Old Man and the Sea', 'year': 1952},
    {'author': 'J. R. R. Tolkien', 'title': 'The Hobbit', 'year': 1937},
    {'author': 'J. R. R. Tolkien', 'title': 'The Fellowship of the Ring', 'year': 1954},
    {'author': 'J. R. R. Tolkien', 'title': 'The Two Towers', 'year': 1954},
    {'author': 'J. R. R. Tolkien', 'title': 'The Return of the King', 'year': 1955},
]

配列の中の連想配列(辞書)へ要素を追加する

各本(book)へ連番idを追加します。

PHP
foreach ($books as $index => $book) {
    $books[$index]['id'] = $index + 1;
}
Python
for index, book in enumerate(books):
    books[index]['id'] = int(index) + 1

配列の中の連想配列(辞書)の要素を削除する

各本(book)から連番idを削除します。

PHP
foreach ($books as $index => $book) {
    unset($books[$index]['id']);
}
Python
for index, book in enumerate(books):
    del books[index]['id']

縦の値の配列を取得する(array_column)

テーブルで見た場合の縦の値の配列を取得します。

PHP
$authors = array_column($books, 'author');

$titles = array_column($books, 'title');

$years = array_column($books, 'year');
Python
authors = [book.get('author') for book in books]

titles = [book.get('title') for book in books]

years = [book.get('year') for book in books]

縦の値によって順に並び変える(array_multisort)

以下の例はまず作者の名前をアルファベット順に並べた後、
同じ作者の中で作品名をアルファベット順に並び替えています。
(ORDER BY author ASC, title ASC)

PHP
array_multisort(
    array_column($books, 'author'), SORT_ASC, SORT_STRING,
    array_column($books, 'title'), SORT_ASC, SORT_STRING,
    $books
);

foreach ($books as $book) {
	echo json_encode($book) . '<br>';
}

Pythonで上記内容と同じ結果を取得するには、
「後」に並び変える作品名を並び変えた後、作者名を並び変えます。

Python
import operator
import json
books = sorted(books, key = operator.itemgetter('title'), reverse=False) 
books = sorted(books, key = operator.itemgetter('author'), reverse=False)

for book in books:
    print(json.dumps(book))

JSON文字列による出力結果は双方同じものとなります。

JSON
{"author": "Ernest Hemingway", "title": "The Old Man and the Sea", "year": 1952}
{"author": "Ernest Hemingway", "title": "The Snows of Kilimanjaro", "year": 1940}
{"author": "Ernest Hemingway", "title": "The Sun Also Rises", "year": 1926}
{"author": "Franz Kafka", "title": "The Castle", "year": 1926}
{"author": "Franz Kafka", "title": "The Metamorphosis", "year": 1915}
{"author": "J. R. R. Tolkien", "title": "The Fellowship of the Ring", "year": 1954}
{"author": "J. R. R. Tolkien", "title": "The Hobbit", "year": 1937}
{"author": "J. R. R. Tolkien", "title": "The Return of the King", "year": 1955}
{"author": "J. R. R. Tolkien", "title": "The Two Towers", "year": 1954}

Discussion

ログインするとコメントできます