使用正则表达式替换Python字典中的元素

huangapple go评论62阅读模式
英文:

Replacing elements of a Python dictionary using regex

问题

我一直在尝试用另一个字典中给定的字符串值替换字典的整数组件。但是,我得到了以下错误:

追溯最近的调用最后):

  File "<string>", line 11, in <module>
  File "/usr/lib/python3.11/json/__init__.py", line 346, in loads
    return _default_decoder.decode(s)
  ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 14 (char 13)

以下是提供的代码。不确定为什么会出现错误。

import re 
from json import loads, dumps

movable = {"movable": [0, 3, 6, 9], "fixed": [1, 4, 7, 10], "mixed": [2, 5, 8, 11]}
int_mapping = {0: "Ar", 1: "Ta", 2: "Ge", 3: "Ca", 4: "Le", 5: "Vi", 6: "Li", 7: "Sc", 8: "Sa", 9: "Ca", 10: "Aq", 11: "Pi"}

movable = dumps(movable)
for key in int_mapping.keys():
    movable = re.sub(r'(?<![0-9])' + str(key) + r'(?![0-9])', int_mapping[key], movable)
    
movable = loads(movable)

我理解这段代码可以以不同的方式轻松编写以获得所需的输出。但是,我有兴趣了解我做错了什么。

英文:

I have been trying to replace integer components of a dictionary with string values given in another dictionary. However, I am getting the following error:

Traceback (most recent call last):


File &quot;&lt;string&gt;&quot;, line 11, in &lt;module&gt;
  File &quot;/usr/lib/python3.11/json/__init__.py&quot;, line 346, in loads
return _default_decoder.decode(s)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File &quot;/usr/lib/python3.11/json/decoder.py&quot;, line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File &quot;/usr/lib/python3.11/json/decoder.py&quot;, line 355, in raw_decode
    raise JSONDecodeError(&quot;Expecting value&quot;, s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 14 (char 13)

The code has been given below. Not sure why I am getting an error.

import re 
from json import loads, dumps

movable = {&quot;movable&quot;: [0, 3, 6, 9], &quot;fixed&quot;: [1, 4, 7, 10], &quot;mixed&quot;: [2, 5, 8, 11]}
int_mapping = {0: &quot;Ar&quot;, 1: &quot;Ta&quot;, 2: &quot;Ge&quot;, 3: &quot;Ca&quot;, 4: &quot;Le&quot;, 5: &quot;Vi&quot;, 6: &quot;Li&quot;, 7: &quot;Sc&quot;, 8: &quot;Sa&quot;, 9: &quot;Ca&quot;, 10: &quot;Aq&quot;, 11: &quot;Pi&quot;}

movable = dumps(movable)
for key in int_mapping.keys():
    movable = re.sub(&#39;(?&lt;![0-9])&#39; + str(key) + &#39;(?![0-9])&#39;, int_mapping[key], movable)
    
movable = loads(movable)

I understand that this code can easily be written in a different way to get the desired output. However, I am interested to understand what I am doing wrong.

答案1

得分: 2

如果你在调用json.loads之前打印movable的样子,你会看到问题所在:

for key in int_mapping.keys():
    movable = re.sub('(?<![0-9])' + str(key) + '(?![0-9])', int_mapping[key], movable)
print(movable)

输出结果:

{"movable": [Ar, Ca, Li, Ca], "fixed": [Ta, Le, Sc, Aq], "mixed": [Ge, Vi, Sa, Pi]}

这些字符串(ArCa...)没有引号,因此它不是有效的JSON。

如果你选择继续你的方式,你必须添加&quot;

movable = re.sub(
    '(?<![0-9])' + str(key) + '(?![0-9])', 
    '&quot;' + int_mapping[key] + '&quot;', 
    movable)

(注意&quot;&quot; + int_mapping[key] + &quot;&quot;

这将产生:

{"movable": ["Ar", "Ca", "Li", "Ca"], "fixed": ["Ta", "Le", "Sc", "Aq"], "mixed": ["Ge", "Vi", "Sa", "Pi"]}

话虽如此...最好的做法可能是遍历movable的值,将它们替换为int_mapping中的值。类似这样:

mapped_movable = {}
for key, val in movable.items():
    mapped_movable[key] = [int_mapping[v] for v in val]
print(mapped_movable)
英文:

If you print how movable looks like right before calling json.loads, you'll see what the problem is:

for key in int_mapping.keys():
    movable = re.sub(&#39;(?&lt;![0-9])&#39; + str(key) + &#39;(?![0-9])&#39;, int_mapping[key], movable)
print(movable)

outputs:

{&quot;movable&quot;: [Ar, Ca, Li, Ca], &quot;fixed&quot;: [Ta, Le, Sc, Aq], &quot;mixed&quot;: [Ge, Vi, Sa, Pi]}

Those strings (Ar, Ca...) are not quoted, therefore it is not valid JSON.

If you choose to continue the way you're going, you must add the &quot;:

movable = re.sub(
    &#39;(?&lt;![0-9])&#39; + str(key) + &#39;(?![0-9])&#39;, 
    &#39;&quot;&#39; + int_mapping[key] + &#39;&quot;&#39;, 
    movable)

(notice the &#39;&quot;&#39; + int_mapping[key] + &#39;&quot;&#39;)

Which produces:

{&quot;movable&quot;: [&quot;Ar&quot;, &quot;Ca&quot;, &quot;Li&quot;, &quot;Ca&quot;], &quot;fixed&quot;: [&quot;Ta&quot;, &quot;Le&quot;, &quot;Sc&quot;, &quot;Aq&quot;], &quot;mixed&quot;: [&quot;Ge&quot;, &quot;Vi&quot;, &quot;Sa&quot;, &quot;Pi&quot;]}

This said... you are probably much better off by just walking the movable values and substituting them by the values in int_mapping. Something like:

mapped_movable = {}
for key, val in movable.items():
    mapped_movable[key] = [int_mapping[v] for v in val]
print(mapped_movable)

答案2

得分: 1

以下是代码的翻译部分:

...
movable = {
    k: [int_mapping[v] for v in values]
    for k, values in movable.items()
}
print(type(movable))
print(movable)

输出:

&lt;type &#39;dict&#39;&gt;
{&#39;mixed&#39;: [&#39;Ge&#39;, &#39;Vi&#39;, &#39;Sa&#39;, &#39;Pi&#39;], &#39;fixed&#39;: [&#39;Ta&#39;, &#39;Le&#39;, &#39;Sc&#39;, &#39;Aq&#39;], &#39;movable&#39;: [&#39;Ar&#39;, &#39;Ca&#39;, &#39;Li&#39;, &#39;Ca&#39;]}
英文:

You could use a dict comprehension and make the mapping replacements directly in Python:

...
movable = {
    k: [int_mapping[v] for v in values]
    for k, values in movable.items()
}
print(type(movable))
print(movable)

Out:

&lt;type &#39;dict&#39;&gt;
{&#39;mixed&#39;: [&#39;Ge&#39;, &#39;Vi&#39;, &#39;Sa&#39;, &#39;Pi&#39;], &#39;fixed&#39;: [&#39;Ta&#39;, &#39;Le&#39;, &#39;Sc&#39;, &#39;Aq&#39;], &#39;movable&#39;: [&#39;Ar&#39;, &#39;Ca&#39;, &#39;Li&#39;, &#39;Ca&#39;]}

huangapple
  • 本文由 发表于 2023年2月9日 01:41:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/75389737.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定