2

変換しようとしています:

datalist = [u"{gallery: 'gal1', smallimage: 'http://www.styleever.com/media/catalog/product/cache/1/small_image/445x370/17f82f742ffe127f42dca9de82fb58b1/2/_/2_12.jpg',largeimage: 'http://www.styleever.com/media/catalog/product/cache/1/image/9df78eab33525d08d6e5fb8d27136e95/2/_/2_12.jpg'}",
 u"{gallery: 'gal1', smallimage: 'http://www.styleever.com/media/catalog/product/cache/1/small_image/445x370/17f82f742ffe127f42dca9de82fb58b1/3/_/3_13.jpg',largeimage: 'http://www.styleever.com/media/catalog/product/cache/1/image/9df78eab33525d08d6e5fb8d27136e95/3/_/3_13.jpg'}",
 u"{gallery: 'gal1', smallimage: 'http://www.styleever.com/media/catalog/product/cache/1/small_image/445x370/17f82f742ffe127f42dca9de82fb58b1/5/_/5_3_1.jpg',largeimage: 'http://www.styleever.com/media/catalog/product/cache/1/image/9df78eab33525d08d6e5fb8d27136e95/5/_/5_3_1.jpg'}",
 u"{gallery: 'gal1', smallimage: 'http://www.styleever.com/media/catalog/product/cache/1/small_image/445x370/17f82f742ffe127f42dca9de82fb58b1/1/_/1_22.jpg',largeimage: 'http://www.styleever.com/media/catalog/product/cache/1/image/9df78eab33525d08d6e5fb8d27136e95/1/_/1_22.jpg'}",
 u"{gallery: 'gal1', smallimage: 'http://www.styleever.com/media/catalog/product/cache/1/small_image/445x370/17f82f742ffe127f42dca9de82fb58b1/4/_/4_7_1.jpg',largeimage: 'http://www.styleever.com/media/catalog/product/cache/1/image/9df78eab33525d08d6e5fb8d27136e95/4/_/4_7_1.jpg'}"]

python dict を含む一覧を表示します。キーワードを使用して値を抽出しようとすると、次のエラーが発生しました。

for i in datalist:
    print i['smallimage']
   ....:     

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-20-686ea4feba66> in <module>()
      1 for i in datalist:
----> 2     print i['smallimage']
      3 

TypeError: string indices must be integers

Unicode Dict を含むリストを Dict に変換するにはどうすればよいですか?

4

6 に答える 6

9

You could use the demjson module which has a non-strict mode that handles the data you have:

import demjson

for data in datalist:
    dct = demjson.decode(data)
    print dct['gallery'] # etc...
于 2013-06-17T13:00:42.410 に答える
3

この場合、正規表現を手作りして、これらを Python として評価できるものにします。

import re
import ast
from functools import partial

keys = re.compile(r'(gallery|smallimage|largeimage)')
fix_keys = partial(keys.sub, r'"\1"')

for entry in datalist:
    entry = ast.literal_eval(fix_keys(entry))

はい、これには制限があります。ただし、このセットでは機能し、キーが一致する限り堅牢です。正規表現は保守が簡単です。さらに、これは外部依存関係を使用せず、すべて既に含まれているバッテリーに基づいています。

結果:

>>> for entry in datalist:
...     print ast.literal_eval(fix_keys(entry))
... 
{'largeimage': 'http://www.styleever.com/media/catalog/product/cache/1/image/9df78eab33525d08d6e5fb8d27136e95/2/_/2_12.jpg', 'gallery': 'gal1', 'smallimage': 'http://www.styleever.com/media/catalog/product/cache/1/small_image/445x370/17f82f742ffe127f42dca9de82fb58b1/2/_/2_12.jpg'}
{'largeimage': 'http://www.styleever.com/media/catalog/product/cache/1/image/9df78eab33525d08d6e5fb8d27136e95/3/_/3_13.jpg', 'gallery': 'gal1', 'smallimage': 'http://www.styleever.com/media/catalog/product/cache/1/small_image/445x370/17f82f742ffe127f42dca9de82fb58b1/3/_/3_13.jpg'}
{'largeimage': 'http://www.styleever.com/media/catalog/product/cache/1/image/9df78eab33525d08d6e5fb8d27136e95/5/_/5_3_1.jpg', 'gallery': 'gal1', 'smallimage': 'http://www.styleever.com/media/catalog/product/cache/1/small_image/445x370/17f82f742ffe127f42dca9de82fb58b1/5/_/5_3_1.jpg'}
{'largeimage': 'http://www.styleever.com/media/catalog/product/cache/1/image/9df78eab33525d08d6e5fb8d27136e95/1/_/1_22.jpg', 'gallery': 'gal1', 'smallimage': 'http://www.styleever.com/media/catalog/product/cache/1/small_image/445x370/17f82f742ffe127f42dca9de82fb58b1/1/_/1_22.jpg'}
{'largeimage': 'http://www.styleever.com/media/catalog/product/cache/1/image/9df78eab33525d08d6e5fb8d27136e95/4/_/4_7_1.jpg', 'gallery': 'gal1', 'smallimage': 'http://www.styleever.com/media/catalog/product/cache/1/small_image/445x370/17f82f742ffe127f42dca9de82fb58b1/4/_/4_7_1.jpg'}
于 2013-06-17T12:57:28.680 に答える
3

別の考えとして、リストは適切にフォーマットされた Yaml です。

> yaml.load(u'{foo: "bar"}')['foo']
'bar'

そして、本当に凝ってすべてを一度に解析したい場合は、次のようにします。

> data = yaml.load('['+','.join(datalist)+']')
> data[0]['smallimage']
'http://www.styleever.com/media/catalog/product/cache/1/small_image/445x370/17f82f742ffe127f42dca9de82fb58b1/2/_/2_12.jpg'
> data[3]['gallery']
'gal1'
于 2013-06-17T13:09:51.657 に答える
2

json.loads辞書のキーが引用符で囲まれている場合は、文字列をロードするために使用できます。

import json
for i in datalist:
   print json.loads(i)['smallimage']

ast.literal_evalあまりにもうまくいっただろう...)

ただし、そのままでは、これは古い学校で機能しevalます。

>>> class Mdict(dict):
...     def __missing__(self,key):
...        return key
... 
>>> eval(datalist[0],Mdict(__builtins__=None))
{'largeimage': 'http://www.styleever.com/media/catalog/product/cache/1/image/9df78eab33525d08d6e5fb8d27136e95/2/_/2_12.jpg', 'gallery': 'gal1', 'smallimage': 'http://www.styleever.com/media/catalog/product/cache/1/small_image/445x370/17f82f742ffe127f42dca9de82fb58b1/2/_/2_12.jpg'}

これはおそらくインジェクション攻撃に対して脆弱であるため、文字列が信頼できるソースからのものである場合にのみ使用してください。


最後に、標準ライブラリのみを使用し、インジェクション攻撃に対して脆弱ではありませんが、短い解決策が必要な人のために... この小さな宝石はトリックを行います (辞書キーが有効な識別子であると仮定します)!

import ast
class RewriteName(ast.NodeTransformer):
    def visit_Name(self,node):
        return ast.Str(s=node.id)

transformer = RewriteName()
for x in datalist:
    tree = ast.parse(x,mode='eval')
    transformer.visit(tree)
    print ast.literal_eval(tree)['smallimage']
于 2013-06-17T12:51:33.487 に答える
0

あなたのデータリストはlistユニコード文字列です。

evalキーが適切に引用されていない場合を除いて、 を使用できます。あなたができることは、その場で鍵を再引用することですreplace

for i in datalist:
    my_dict = eval(i.replace("gallery", "'gallery'").replace("smallimage", "'smallimage'").replace("largeimage", "'largeimage'"))
    print my_dict["smallimage"]
于 2013-06-17T13:01:23.890 に答える
-4

reまたはjson...を使用するなど、すべての余分なものが必要な理由がわかりません。

fdict = {str(k): v for (k, v) in udict.items()}

udictdictある はどこですか。unicodeに変換するだけstrです。与えられたデータでは、簡単に...

datalist = [dict((str(k), v) for (k, v) in i.items()) for i in datalist]

簡単なテスト:

>>> datalist = [{u'a':1,u'b':2},{u'a':1,u'b':2}]
[{u'a': 1, u'b': 2}, {u'a': 1, u'b': 2}]
>>> datalist = [dict((str(k), v) for (k, v) in i.items()) for i in datalist]
>>> datalist
[{'a': 1, 'b': 2}, {'a': 1, 'b': 2}]

いいえimport reまたはimport json。シンプルかつ迅速。

于 2013-06-17T13:04:53.117 に答える