Python データ構造アルゴリズムの質問 18: 特定のフィールドごとにレコードをグループ化する

質問:

辞書またはインスタンスのシーケンスがあり、日付などの特定のフィールドごとにグループ化してそれらを反復処理したいとします。

解決:

itertools.groupby() 関数は、このようなデータのグループ化操作に非常に役立ちます。デモの目的で、次の辞書のリストがすでにあると仮定します。

rows = [
    {
    
    'address': '5412 N CLARK', 'date': '07/01/2012'},
    {
    
    'address': '5148 N CLARK', 'date': '07/04/2012'},
    {
    
    'address': '5800 E 58TH', 'date': '07/02/2012'},
    {
    
    'address': '2122 N CLARK', 'date': '07/03/2012'},
    {
    
    'address': '5645 N RAVENSWOOD', 'date': '07/02/2012'},
    {
    
    'address': '1060 W ADDISON', 'date': '07/02/2012'},
    {
    
    'address': '4801 N BROADWAY', 'date': '07/01/2012'},
    {
    
    'address': '1039 W GRANVILLE', 'date': '07/04/2012'},
]

ここで、日付ごとにグループ化されたデータのチャンクを反復処理するとします。これを行うには、まず指定したフィールド (この場合は日付) で並べ替えてから、 itertools.groupby() 関数を呼び出す必要があります。

from operator import itemgetter from itertools import groupby
# Sort by the desired field first
rows.sort(key=itemgetter('date'))
# Iterate in groups
for date, items in groupby(rows, key=itemgetter('date')):
print(date) for i in items:
print(' ', i)

操作結果:

07/01/2012
  {
    
    'date': '07/01/2012', 'address': '5412 N CLARK'}
  {
    
    'date': '07/01/2012', 'address': '4801 N BROADWAY'}
07/02/2012
  {
    
    'date': '07/02/2012', 'address': '5800 E 58TH'}
  {
    
    'date': '07/02/2012', 'address': '5645 N RAVENSWOOD'}
  {
    
    'date': '07/02/2012', 'address': '1060 W ADDISON'}
07/03/2012
  {
    
    'date': '07/03/2012', 'address': '2122 N CLARK'}
07/04/2012
  {
    
    'date': '07/04/2012', 'address': '5148 N CLARK'}
  {
    
    'date': '07/04/2012', 'address': '1039 W GRANVILLE'}

groupby() 関数はシーケンス全体をスキャンし、同じ連続値 (または指定されたキー関数によって返された同じ値) を持つ要素のシーケンスを見つけます。各反復で、要素値がすべて上記の値と等しいグループ内のすべてのオブジェクトを生成できる値とイテレータ オブジェクトを返します。

非常に重要な準備ステップは、指定されたフィールドに従ってデータを並べ替えることです。groupby() は連続する要素のみをチェックするため、事前に並べ替えが行われていない場合、グループ化関数は望ましい結果を取得しません。

日付フィールドに基づいてデータを大規模なデータ構造にグループ化し、ランダム アクセスを許可するだけの場合は、defaultdict() を使用して複数値の辞書を構築することをお勧めします。

from collections import defaultdict rows_by_date = defaultdict(list) for row in rows:
    rows_by_date[row['date']].append(row)

指定した日付ごとに対応するレコードに簡単にアクセスできます。

>>> for r in rows_by_date['07/01/2012']:
... print(r)
...
{
    
    'date': '07/01/2012', 'address': '5412 N CLARK'}
 {
    
    'date': '07/01/2012', 'address': '4801 N BROADWAY'}
>>>

メモリ使用量をあまり気にしない場合は、このメソッドは、最初に並べ替えてから groupby() 関数を繰り返すよりも高速に実行されます。

おすすめ

転載: blog.csdn.net/m0_68635815/article/details/135442342