5

プロジェクトの1つでkendoUIグリッドを使用しています。APIを使用してデータを取得したところ、json/dictionaryに「不要な」データが追加されていることがわかりました。jsonをPyramidバックエンドに戻した後、これらのキーを削除する必要があります。問題は、辞書はどんな深さでもかまいません、そして私は前もって深さを知りません。

例:

product = {
    id: "PR_12"
    name: "Blue shirt",
    description: "Flowery shirt for boys above 2 years old",
    _event: {<some unwanted data here>},
    length: <some unwanted data>,
    items: [{_event: {<some rubbish data>}, length: <more rubbish>, price: 23.30, quantity: 34, color: "Red", size: "Large"}, {_event: {<some more rubbish data>}, length: <even more rubbish>, price: 34.50, quantity: 20, color: "Blue", size: "Large"} ....]
}

特に「_event」と「length」の2つのキーを削除したいと思います。データを削除する再帰関数を書いてみましたが、うまくいかないようです。誰か助けてもらえますか?

これが私が持っているものです:

def remove_specific_key(the_dict, rubbish):
  for key in the_dict:
    if key == rubbish:
      the_dict.pop(key)
    else:
      # check for rubbish in sub dict
      if isinstance(the_dict[key], dict):
        remove_specific_key(the_dict[key], rubbish)

      # check for existence of rubbish in lists
      elif isinstance(the_dict[key], list):
        for item in the_dict[key]:
          if item == rubbish:
            the_dict[key].remove(item)
   return the_dict
4

3 に答える 3

7

remove_specific_key( renamed remove_keys) が最初の引数として任意のオブジェクトを受け入れることを許可すると、コードを簡素化できます。

def remove_keys(obj, rubbish):
    if isinstance(obj, dict):
        obj = {
            key: remove_keys(value, rubbish) 
            for key, value in obj.iteritems()
            if key not in rubbish}
    elif isinstance(obj, list):
        obj = [remove_keys(item, rubbish)
                  for item in obj
                  if item not in rubbish]
    return obj

複数のキーを削除したいので、rubbish特定の 1 つのキーではなくセットにすることもできます。上記のコードでは、'_event' および 'length' キーを次のように削除します。

product = remove_keys(product, set(['_event', 'length']))

編集: Python2.7 で導入されたdict comprehensionremove_keyを使用します。古いバージョンの Python の場合、同等のものは次のようになります。

    obj = dict((key, remove_keys(value, rubbish))
               for key, value in obj.iteritems()
               if key not in rubbish)
于 2012-04-16T18:10:03.690 に答える
4

探しているキーが正確にわかっているため、辞書を反復するときに変更するのは不必要です。また、口述のリストが正しく処理されていません。

def remove_specific_key(the_dict, rubbish):
    if rubbish in the_dict:
        del the_dict[rubbish]
    for key, value in the_dict.items():
        # check for rubbish in sub dict
        if isinstance(value, dict):
            remove_specific_key(value, rubbish)

        # check for existence of rubbish in lists
        elif isinstance(value, list):
            for item in value:
                if isinstance(item, dict):
                    remove_specific_key(item, rubbish)
于 2012-04-16T17:56:12.303 に答える
1

dict または list は反復中に削除できないため、反復子をテスト関数に置き換えます。

def remove_specific_key(the_dict, rubbish):
    if the_dict.has_key(rubbish):
        the_dict.pop(rubbish)
    else:
        for key in the_dict:
            if isinstance(the_dict[key], dict):
                remove_specific_key(the_dict[key], rubbish)
            elif isinstance(the_dict[key], list):
                if the_dict[key].count(rubbish):
                    the_dict[key].remove(rubbish)
    return the_dict


d = {"a": {"aa": "foobar"}}
remove_specific_key(d, "aa")
print d

d = {"a": ["aa", "foobar"]}
remove_specific_key(d, "aa")
print d
于 2012-04-16T18:09:09.473 に答える