2012-10-27 7 views
10

可能性の重複をASCIIに変換します
How to get string Objects instead Unicode ones from JSON in Python?Pythonの:Unicodeから文字列の複雑な辞書が

私はJSON API呼び出しから解析されたマルチレベルの辞書などの入力がたくさんあります。文字列はすべてユニコードであるため、u'stuff like this'がたくさんあることを意味します。私はjqを使用して結果を再生し、これらの結果をASCIIに変換する必要があります。

は、私はちょうどそのようにそれを変換するための関数を書くことができます知っている:

def convert(input): 
    if isinstance(input, dict): 
     ret = {} 
     for stuff in input: 
      ret = convert(stuff) 
    elif isinstance(input, list): 
     ret = [] 
     for i in range(len(input)) 
      ret = convert(input[i]) 
    elif isinstance(input, str): 
     ret = input.encode('ascii') 
    elif : 
     ret = input 
    return ret 

がこのさえ正しいですか?わからない。それは私があなたに尋ねたいものではありません。

私が求めているのは、これが問題の典型的な強硬な解決策です。より良い方法が必要です。より平凡な方法。私はアルゴリズムの専門家ではありませんが、この方も特に高速に見えません。

もっと良い方法がありますか?そうでない場合は、この機能を改善できますか?


ポスト答え編集

Mark Amery's answerは正しいですが、私はそれの修正版を投稿したいと思います。彼の機能は、Python 2.7以降で動作し、私は2.6によので、それを変換する必要がありました:

def convert(input): 
    if isinstance(input, dict): 
     return dict((convert(key), convert(value)) for key, value in input.iteritems()) 
    elif isinstance(input, list): 
     return [convert(element) for element in input] 
    elif isinstance(input, unicode): 
     return input.encode('utf-8') 
    else: 
     return input 
+1

Python 2をお使いの場合、unicodeは 'str'のインスタンスではなく' unicode'のインスタンスです。また、 'list'と' dict'処理では間違っています。 – agf

+0

リストの場合、反復可能なものを扱うことを検討することをお勧めします。いずれの場合でも、if文のその枝を 'ret = [入力のxの変換(x)]'で置き換えることができます。また、あなたの辞書の場合を確認してください。 'ret'はディクショナリの最後のキーが変換されたものだけを含みます。 –

+0

@MichaelMior説明したように繰り返し可能なものを扱うことの問題は、すべてのiterableがリストのようなものではないということです。例えば、辞書は反復可能ですが、 'ret = [input in xの変換(x)]'は、 'input'が辞書の場合には欲しいものではありません。 –

答えて

23

再帰はここに行くための方法のように思えるが、あなたは、Pythonのバージョン2.xxにしている場合は、チェックしたいですunicodeではなくstrstrタイプはバイト列を表し、unicodeはユニコード文字列を入力しますが、他の文字列を継承せず、インタープリターに表示されているauを先頭に持つユニコードタイプの文字列です) 。

投稿コードにも構文エラーがあります(末尾のelif:elseである必要があります)。入力が辞書またはリストの場合は同じ構造を返しません。 (辞書の場合は、最終的なキーの変換されたバージョンを返します;リストの場合は、最終的な要素の変換されたバージョンを戻しています)どちらも正しくありません。

また、あなたのコードを理解しやすくするために、Pythonicを使います。ここで

、そして、私がお勧めです:

def convert(input): 
    if isinstance(input, dict): 
     return {convert(key): convert(value) for key, value in input.iteritems()} 
    elif isinstance(input, list): 
     return [convert(element) for element in input] 
    elif isinstance(input, unicode): 
     return input.encode('utf-8') 
    else: 
     return input 

最後にひとつの事。私はencode('ascii')encode('utf-8')に変更しました。私の推論は次の通りです:ASCII文字セットの文字だけを含むUnicode文字列は、utf-8でエンコードされたときにASCIIでエンコードされたときと同じバイト文字列で表されるため、ASCIIの代わりにutf-8を使用すると、あなたが扱っているUnicode文字列がASCII文字だけを使用している限り、変更は見えません。しかし、この変更により、Unicode文字セット全体から文字列を処理できるように関数の範囲が拡張されています。

+1

+1。あなたは再帰についてのコメントを除いて:)再帰は、ほとんどの種類のツリートラバーサル、およびほとんどの解析問題に役立ちます。再帰は、特に関数型プログラミングに関しては、しばしば「行く方法」です。 –

+1

@JoelCornett十分に公正。私のコメントは広く反反復であることを意図していませんでした。私は再帰が木のトラバースの問題に意味があることを知ることができます。その中で、多くの解析問題はサブセットです。私はちょうどかなりこのゲームに新しいとcompsciバックグラウンドからではないので、私はまだその自然の問題を遭遇していない。私が見た再帰の例は無意味であり、反復的なものになる傾向があります。これは、私が突然 "うわー、再帰*が本当にここのものを単純化する"ことになった初めてのことです。 :) –

+0

ありがとう、これは本当にいいです。これは疑いなく、これはおそらく複製されているという質問の回答よりも優れています。 – Dreen

関連する問題