0

私は文字列を持っています:

A = "{user_id:34dd833,category:secondary,items:camera,type:sg_ser}"

それをpython辞書に変換する必要があるため、次のようになります。

A = {"user_id":"34dd833", "category": "secondary", "items": "camera", "type": "sg_ser"}

さらに、次の 2 つの問題があります。

1: "items" キーには、次のように複数の値が必要です。

A = {"user_id":34dd833, "category": "secondary", "items": "camera,vcr,dvd", "type": "sg_ser"}

これは明らかに次のような文字列の形式になります。

A = "{user_id:34dd833,category:secondary,items:camera,vcr,dvd,type:sg_ser}"

したがって、コンマ区切りに基づいて何かを一般化することは役に立たなくなります。

2: 文字列の順序もランダムにすることができます。したがって、文字列は次のようにもなります。

A = "{category:secondary,type:sg_ser,user_id:34dd833,items:camera,vcr,dvd}"

これにより、注文ごとに薄いと仮定するプロセスが誤ったものになります。

そのような状況で何をすべきか?どうもありがとう。

4

2 に答える 2

7

あなたの入力が引用符やエスケープを行わないと仮定できる場合(あなたのはそうではありませんが、それは必ずしもそれが良い仮定であることを意味するわけではありません)、コンマで区切られた複数のキーを持つことはできず、複数の値だけを持つことはできません(それ以外の場合、形式があいまいになるため、これおそらく適切な仮定です...):

まず、中かっこを削除してから、コロンで分割します。

>>> A = "{user_id:34dd833,category:secondary,items:camera,vcr,dvd,type:sg_ser}"
>>> A[1:-1].split(':')
['user_id', '34dd833,category', 'secondary,items', 'camera,vcr,dvd,type', 'sg_ser']

したがって、最初のエントリは最初のキーで、最後のエントリは最後の値であり、その間のすべてのエントリは N 番目の値の後にコンマが続き、その後に N+1 番目のキーが続きます。そこには他のコンマがあるかもしれませんが、最後のコンマは常に N+1 番目のキーから N 番目の値を分割します。(そして、これは N=0 でも機能します。コンマがないため、最後のコンマは 0 番目のキーから何も分割しません。しかし、残念ながら、最後のエントリでは機能しません。これについては後で説明します。)

これを簡潔にする方法はいくつかありますが、最初にコードとして明示的に記述して、その仕組みを理解できるようにしましょう。

>>> d = {}
>>> entries = A[1:-1].split(':')
>>> for i in range(len(entries)-1):
...     key = entries[i].rpartition(',')[-1]
...     value = entries[i+1].rpartition(',')[0]
...     d[key] = value

これはほぼ正しいです:

>>> d
{'category': 'secondary', 'items': 'camera,vcr,dvd', 'type': '', 'user_id': '34dd833'}

上記のように、最後のものには機能しません。その理由は明らかです。そうでない場合はrpartition(',')、最後の値に対して何が返されるかを確認してください。,手動でパッチを適用するか、最後に余分なものを詰め込んでごまかすことができます( entries = (A[1:-1] + ',').split(':'))。しかし、考えてみると、rsplitの代わりにrpartition,[0]が正しいことを行います。では、代わりにそうしましょう。

では、これを少しきれいにするにはどうすればよいでしょうか。

entriesまず、隣接するペアのリストに変換しましょう。ここで、各ペアのそれぞれ(n, nplus1)n.rpartition(',')[-1]キーでありnplus1.rsplit(',', 1)[0]、対応する値です。そう:

>>> A = "{user_id:34dd833,category:secondary,items:camera,vcr,dvd,type:sg_ser}"
>>> entries = A[1:-1].split(':')
>>> adjpairs = zip(entries, entries[1:])
>>> d = {k.rpartition(',')[-1]: v.rsplit(',', 1)[0] for k, v in adjpairs}
于 2013-08-09T22:59:46.793 に答える
2

これは別の方法です(特に堅牢ではありませんが、サンプルデータで可能であることを示しています):

import re
text = "{user_id:34dd833,category:secondary,items:camera,vcr,dvd,type:sg_ser}"
print dict(re.findall(r'(\w+):(.*?)(?=(?:,\w+:)|$)', text.strip('{}')))
# {'category': 'secondary', 'items': 'camera,vcr,dvd', 'user_id': '34dd833', 'type': 'sg_ser'}
于 2013-08-09T23:31:36.967 に答える