2017-02-01 8 views
1

辞書を文字列に変換したいと思います。初心者レベルの質問は、私が付着しなければならないいくつかのルールによって複雑さは何を次のようになります。辞書キーを任意の順序で処理しています

  • は特に出て来なければなら知らキーのリストがあり、任意の順序
  • 知られているキーのそれぞれは任意ですすなわち、辞書に存在しない可能性があります。
  • 既知のキーのうち少なくとも1つが辞書に存在することが保証されています。
  • 辞書には追加のキーが含まれている可能性があります。彼らは後に知られているキーを来なければならないし、そのためには、私はキーが

他の人の前に、いくつかの辞書のキーを処理するニシキヘビの方法は何であるの辞書に追加される順序についての仮定を行うことができない

  • 重要ではないのですか?
    data = { 
        "tags": "one, two", 
        "slug": "post-title", 
        "date": "2017-02-01", 
        "title": "Post Title", 
    } 
    
    print(format_data(data)) 
    
    data = { 
        "format": "book", 
        "title": "Another Post Title", 
        "date": "2017-02-01", 
        "slug": "another-post-title", 
        "custom": "data", 
    } 
    
    print(format_data(data)) 
    
    Title: Post Title 
    Slug: post-title 
    Date: 2017-02-01 
    Tags: one, two 
    
    Title: Another Post Title 
    Slug: another-post-title 
    Date: 2017-02-01 
    Custom: data 
    Format: book 
    

    この機能が期待される結果を提供しないが

    def format_data(input_data): 
        data = dict(input_data) 
        output = [] 
        for key in ["title", "slug", "date", "modified", "category", "tags"]: 
         if key in data: 
          output.append("{}: {}".format(key.title(), data[key])) 
          del data[key] 
    
        if data: 
         for key in data: 
          output.append("{}: {}".format(key.title(), data[key])) 
    
        return "\n".join(output) 
    
    が、それは私がより良いアプローチがあるかもしれないと思わせるいくつかの問題があります。

    はこれまでのところ、私は以下の機能を持っています。つまり、output.append()行が複製され、入力データ構造がコピーされて副作用なしに変更が可能になります。

    要約すると、特定の順序で、そして他のキーの前に、いくつかのキーをどのように処理できますか?

  • +1

    あなたの実装に特に問題はありません。 'if data:'は不要ですが、それはそれです。 – glibdud

    +1

    反復している間に実際に 'del data [key]'したいのですか(それは悪い習慣です)、あるいはそれをして、既知のキーが2回以上反復されないようにしますか? – smci

    +0

    入力がまだ辞書ではない場合(あなたの例では表現されていない)でない限り、 'dict(input_data)'を持つ必要はありません。 – skrrgwasme

    答えて

    2

    私はあなたは、単にリストの内包表記の組を実行することを示唆している:希望キーの一つであり、残りの1 。一度に1つずつではなく、一括して希望の順序で連結します。これにより、出力を構築する単一のコマンドに対する重要なステップが削減されます。

    最初の理解では、dict内の目的のキーが検索されます。 2番目のキーは、「希望の」リスト内のではなく、を検索します。

    def format_data(input_data): 
        data = dict(input_data) 
        key_list = ["title", "slug", "date", "modified", "category", "tags"] 
        output = ["{}: {}".format(key.title(), data[key]) for key in key_list if key in data] + \ 
          ["{}: {}".format(key.title(), data[key]) for key in data if key not in key_list] 
        return "\n".join(output) 
    
    0

    完全に編集するには、主キーのリストを取得します(設定ファイルに設定または設定したい場合はそれらを渡してから、辞書の先頭に設定します)。

    私はあなたが今何を意味するかを参照思う:

    これを試してみてください:

    from collections import OrderedDict 
    data = {'aaa': 'bbbb', 
    'custom': 'data', 
    'date': '2017-02-01', 
    'foo': 'bar', 
    'format': 'book', 
    'slug': 'another-post-title', 
    'title': 'Another Post Title'} 
    
    def format_data(input_data): 
        primary_keys = ["title", "slug", "date", "modified", "category", "tags"] 
        data = OrderedDict((k, input_data.get(k)) for k in primary_keys + input_data.keys()) 
        output = [] 
        for key, value in data.items(): 
         if value: 
          output.append("{}: {}".format(key.title(), value)) 
        return "\n".join(output) 
    
    print(format_data(data)) 
    
    Title: Another Post Title 
    Slug: another-post-title 
    Date: 2017-02-01 
    Aaa: bbbb 
    Format: book 
    Custom: data 
    Foo: bar 
    
    +0

    私は 'OrderedDict'アイデアが好きですが、反復処理中はコレクションから削除しないでください。最初にキーのリストを作成し、リストを反復しながら辞書を自由に変更することができます。実際、smciの質問に対するコメントは良いことになっています。恐らく削除は恐らく事を2回繰り返すのを防ぐためのものでした。注文された辞書でこれ以上必要ではないかもしれません。 – skrrgwasme

    +0

    本当に、私は代替のためのアップデートがあります。 – Kelvin

    +0

    答えをありがとう。しかし、私は入力辞書にキーが追加される順序について仮定することはできません(ソースファイルを1行ずつ読み込み、ソースの順序はランダムです)。私はテンプレートOrderedDictを作成することができると思うすべての既知のキーが予想された順序で追加されますが、再度 - ソースファイルがいくつかの既知のキーが不足している可能性があります。これらの要件を私の質問に加えました。あなたはこれらの問題を解決するためにあなたの答えを試して更新できますか? –

    0

    私は、リストの内包とpop()をお勧めしたい:反復中に削除に関する懸念に

    def format_data(input_data): 
        data = dict(input_data) 
    
        keys = ["title", "slug", "date", "modified", "category", "tags"] 
        output = ['{}: {}'.format(key.title(), data.pop(key)) for key in keys if key in data] 
    
        output.extend(['{}: {}'.format(key.title(), val) for key, val in data.items()]) 
    
        return "\n".join(output) 
    

    - 辞書が評価され、反復はキーのリスト上にあることではないに注意してくださいので、私それは赤い旗だとは思わないでしょう。

    0

    既知のキーと入力辞書のキーの違いを確認します。 iterateools.chainを使用してキーをに設定します。 KeyErrorsをキャッチしてキーを紛失してしまいました。入力をコピーする必要はなく、重複はありません。

    import itertools 
    def format_data(input_data): 
        known_keys = ["title", "slug", "date", "modified", "category", "tags"] 
        xtra_keys = set(input_data.keys()).difference(known_keys) 
        output = [] 
        for key in itertools.chain(known_keys, xtra_keys): 
         try: 
          output.append("{}: {}".format(key.title(), data[key])) 
         except KeyError as e: 
          pass 
        return '\n'.join(output) 
    
    data = {"tags": "one, two", 
         "slug": "post-title", 
         "date": "2017-02-01", 
         "title": "Post Title", 
         "foo": "bar"} 
    
    >>> print format_data(data) 
    Title: Post Title 
    Slug: post-title 
    Date: 2017-02-01 
    Tags: one, two 
    Foo: bar 
    >>> 
    
    関連する問題