これは私の以前の質問に関連しています:ネストされたリストから区切り文字列への変換
区切り文字列形式でデータを送信する外部サービスがあります。これは、最大 3 レベルの深さのアイテムのリストです。レベル 1 は「|」で区切られます。レベル 2 は「;」で区切られます。レベル 3 は「,」で区切られます。各レベルまたは要素には、0 個以上のアイテムを含めることができます。簡単な例は次のとおりです。
a,b;c,d|e||f,g|h;;
これをネストされたリストに変換する関数があります。これは Python での操作方法です。
def dyn_to_lists(dyn):
return [[[c for c in b.split(',')] for b in a.split(';')] for a in dyn.split('|')]
上記の例では、この関数の結果は次のようになります。
>>> dyn = "a,b;c,d|e||f,g|h;;"
>>> print (dyn_to_lists(dyn))
[[['a', 'b'], ['c', 'd']], [['e']], [['']], [['f', 'g']], [['h'], [''], ['']]]
リストの場合、任意のレベルでアイテムが 1 つしかない場合は、1 アイテム リストではなくスカラーとして使用します。空のリストについては、単なる空の文字列として扱います。私はこの機能を思いつきました。これはうまくいきます:
def dyn_to_min_lists(dyn):
def compress(x):
return "" if len(x) == 0 else x if len(x) != 1 else x[0]
return compress([compress([compress([item for item in mv.split(',')]) for mv in attr.split(';')]) for attr in dyn.split('|')])
この関数を使用し、上記の例を使用すると、返されます ( *下記の更新を参照):
[[['a', 'b'], ['c', 'd']], 'e', '', ['f', 'g'], ['h', '', '']]
Python は初めてなので、これが最善の方法であるとは確信していません。これを処理するためのよりクリーンな方法はありますか?
これにより、大量のデータが通過する可能性があります。これを達成するためのより効率的/スケーラブルな方法はありますか?
アップデート
元の圧縮機能にバグが見つかりました。内側のリストに複数のアイテムがある場合、外側のリストは削除できません。これにより、変換が元に戻せなくなります。このために、@Blender の圧縮関数を次のように更新しました。
def __compress(x):
if len(x) > 1:
return x
elif not x:
return ''
else:
if type(x[0]) != list:
return x[0]
else:
return x
これで、次の正しい出力が返されます。
[[['a', 'b'], ['c', 'd']], 'e', '', [['f', 'g']], ['h', '', '']]