私はpythonでAmazon S3バケットに格納されたファイルのエントリを含むネストされた辞書を作成しています。だから私のバケツに私はこのようなファイルをいくつ持っている場合:ネストされた辞書を再帰的に更新するベストプラクティス?
mys3bucket /サブディレクトリ/ world.txt
mys3bucket /サブディレクトリ/ hello.txt
mys3bucket/foobar.txt
をIこの形式でのpythonで辞書を作りたい:
dict = { 'subdir' : { 'world.txt' : 'file', 'hello.txt' : 'file' }, 'foobar.txt' :'file' }
値(「ファイル」)は、この文脈では意味を持たないが、彼らは、ファイルのサイズまたはSで置換することができます何か他のもの(この質問のために重要ではない)。要点は、サブディレクトリのために辞書がネストされなければならないことであり、明らかにネストのレベルは特定のツリーの深さによって異なります。デフォルトのバケット名はちょうど私が上でコードをテストできるようにした公共バケットに設定されている
#!/usr/bin/python
import httplib
from re import compile as recomp
pattern = recomp("<Key>(.*?)<\/Key>")
def main(bucketname='elasticmapreduce'):
url = bucketname + '.s3.amazonaws.com'
HTTPconnection = httplib.HTTPConnection(url)
HTTPconnection.request("GET", "/")
response = HTTPconnection.getresponse()
content = response.read()
fileslist = pattern.findall(content)
filesdict = {}
def intoDict(path,mydict):
if len(path) == 1:
mydict[path[0]] = 'file'
return mydict
else:
name = path.pop(0)
if name in mydict:
mydict[name] = intoDict(path,mydict[name])
else:
mydict[name] = intoDict(path,{})
return mydict
for line in fileslist:
splitline = line.split('/')
if splitline[-1] != '':
filesdict = intoDict(splitline,filesdict)
return filesdict
:私はすでにこれを行う作業の実装を書かれています。
正規表現の理由は、あなたがバケットを照会するときにS3がXML形式のテキストを返すので、正規表現がそれからファイルパスを取り出すだけなのでです。
私の実装の効率性が不思議です。 forループで見ることができるように、毎回辞書全体をintoDict()
関数に渡しています。それが戻ってくると、それを書き直します。 intoDict()
関数は再帰的/自己参照型であり、これは入れ子の仕組みです。何が起こっているのか説明するのは少し難しいですが、私はあなたが見ることができると思います。最初はdictionary.update()
を使ってfor
ループ内の辞書を更新しようとしていましたが、正しく動作しなかったので、この解決策にはしばらく時間がかかりました。
ネストされた辞書や再帰関数に慣れている人が、これが正しい方法であるかどうか、それがよりうまくいくかどうかについてはコメントできますか?
ありがとう@niemmi、これは本当にクールです! 新しい概念をいくつか紹介しました。''もしpath [i]がd:d [path [i]] = {} 'にないならば、私は' defaultdict'なしで動作するようにコードを変更した。 私が理解できない何か:代入 'd = filesdict'私は、Pythonが2つの辞書間にある種の動的な関連付けを作成すると思いますか?それが愚かな質問であれば、お詫び申し上げます。 –
@KirillVourlakidisまったく愚かな質問ではありません。私はあなたがダイナミックな関連付けによって何を意味するのかは分かりませんが、同じオブジェクトへの参照は2つだけです。 'd = d [path [i]]'行が実行された後、 'd'は子の' dict'を参照します。次のパスが処理されると、そこから参照を維持する必要があるので、ルートから再度開始する必要があります( 'filesdict')。 – niemmi
同じオブジェクトの参照については意味があります。私の頭の中で、私はPythonが辞書全体のコピーを作成し、それらをリンクすることを想像していました。それが変更されると自動的に他のもの、つまり私の「動的な関連」のコメントが変更されます。 私はまだオブジェクト指向のもの全体に頭を浮かべています。 –