或者说这是一个什么样的格式?
比如
{ city: "beijing", device: "Iphone" }
1 JamesMackerel 2022-09-01 16:21:55 +08:00 via iPhone 可以先序列化再用正则替换一下? |
![]() | 2 westoy 2022-09-01 16:25:21 +08:00 js object popen node.js console.log(json) |
3 Hstar 2022-09-01 16:30:15 +08:00 这种格式只存在于代码中,city 和 device 是个变量引用。 输出做不到,非标格式。 |
![]() | 4 caqiko 2022-09-01 16:32:33 +08:00 via Android 为什么要这样输出?这是 js 里的对象 |
![]() | 5 yangg 2022-09-01 16:34:02 +08:00 yaml.dump ? |
6 NessajCN 2022-09-01 16:41:00 +08:00 print("{") for key in dict: print(f'{key}:"{dict[key]",') print("}") |
![]() | 7 lisongeee 2022-09-01 16:41:07 +08:00 |
![]() | 8 ChrisFreeMan 2022-09-01 16:41:53 +08:00 找下有没有 json5 的库,json5 就是类似这种格式 |
10 mylifcc OP |
11 lanlanye 2022-09-01 17:28:23 +08:00 笔试题的话自己写个遍历打印不就好了吗? >>> def pprint(dict_): ... print("{") ... for k, v in dict_.items(): ... print(f' {k}: "{v}",') ... print("}") ... >>> d = {'city': 'Beijing', 'device': 'iPhone'} >>> pprint(d) { city: "Beijing", device: "iPhone", } |
![]() | 13 huangzhe8263 2022-09-01 18:22:16 +08:00 这就不是 python 里的标准格式吧 |
![]() | 14 llsquaer 2022-09-01 18:52:09 +08:00 正则替换. dic_str={'Alice': '2341', 'Beth': '9102', 'Cecil': '3258'} result=re.sub(r"'(.*?)': '(.*?)'" , "1\:\"\2\"", dic_str ) print(result) |
![]() | 15 ysc3839 2022-09-01 18:59:09 +08:00 via Android 自己写个遍历输出就完事了 @mylifcc 是 Javascript(不是 JSON)的 object 格式 |
![]() | 16 ysc3839 2022-09-01 19:09:32 +08:00 一句话的写法: '{' + ', '.join((f'{k}: "{v}"' for k, v in t.items())) + '}' 没有考虑值中含有引号的转移,可以看规则自己改成 v.replace('"', '\\"') |
17 wxf666 2022-09-01 19:12:12 +08:00 @JamesMackerel @llsquaer 正则替换,要考虑不少东西的。比如: 1. 键值对里的值,不一定全是字符串,还可以是数字、列表、字典等 2. 就算是『"(.+?)"\s*:』,也有可能是『'"fake_key": value'』,序列化成『"\"fake_key\": value"』,然后被替换成『"\fake_key\": value 』了 |
19 wxf666 2022-09-01 19:17:40 +08:00 |
20 mmm159357456 2022-09-01 20:03:39 +08:00 不是啊,OP 要的是字典啊,你们推荐的全转换成 string 了 |
21 wxf666 2022-09-01 20:21:36 +08:00 |
23 ershierdu 2022-09-01 20:53:44 +08:00 via iPhone 之前被迫需要用 Python 解析这种结构的字符串,查了一圈,大家都叫它“bad json”… |
24 thinkershare 2022-09-01 21:08:56 +08:00 @mylifcc 如果你只是需要一个这样的字符串, 那么有非常多办法, 如果你需要一个无属性字典, 那么, 没有办法, 因为字典的 key 必须是一个可以哈希化的值, 而你写的属性名称不是任何类型, 因此没办法实现你要的功能. 作为 key 的键, 必须是一个值, 你需要对象那种普通属性是做不到的. |
![]() | 25 Vegetable 2022-09-01 21:31:07 +08:00 |
![]() | 26 LindsayZhou 2022-09-01 21:49:43 +08:00 ![]() Python 的 JSONEncoder 全部是用 Python 写的,没用 C 继承过来重新写一下就行了吧: https://github.com/python/cpython/blob/2ecc195498f3b1256fabc2b66e0d8f6d671fa1d7/Lib/json/encoder.py#L36 |
27 mylifcc OP @LindsayZhou @thinkershare 主要是想知道这是个什么东西,因为这个东西看起来不像是语法错误,但我又说不上是什么,也没想着他是什么指定的格式,就想知道什么地方会生成它,然后什么地方会用到 |
28 wxf666 2022-09-01 22:35:52 +08:00 @mylifcc 这个应该是 js 的对象(字面量)吧: https://zh.Javascript.info/object 试着写了一个( v 站排版原因,行首有若干全角空格): 1. 可以是数字、布尔、空值、字符串、列表、字典的随意组合 2. 除了字典的键会直接字符串化外,其他字符串会遵循 json 的要求,不包含控制字符和 \ "(替换为转义字符或十六进制) from typing import Sequence, Mapping ESCAPE_TABLE = str.maketrans( {chr(i): f'\\u{i:04x}' for i in range(32)} | {k: f'\\{v}' for k, v in zip('\b\t\n\f\r\\"', 'btnfr"\\')} ) def jsonify(obj) -> str: if isinstance(obj, str): return f'"{obj.translate(ESCAPE_TABLE)}"' elif isinstance(obj, Sequence): return f"[{', '.join(map(jsonify, obj))}]" elif isinstance(obj, Mapping): return f"{{{', '.join(f'{k}: {jsonify(v)}' for k, v in obj.items())}}}" else: return str({ None: 'null', True: 'true', False: 'false', }.get(obj, obj)) |
29 JamesMackerel 2022-09-01 22:43:49 +08:00 via iPhone @wxf666 参考 https://blog.dragonslayer.me/archives/115 虽然性能很低就是了(感觉)。如果要性能,应该可以根据语义去做 pretty print ,感觉是一个 json serializer ?不知道好做不好做。 |
30 wxf666 2022-09-02 00:30:51 +08:00 @JamesMackerel @llsquaer @mylifcc 尝试用正则实现了,可在 regexr.com regex101.com 运行 1. 可以是数字、布尔、空值、字符串、列表、字典的随意组合 2. 除了字典的键会直接字符串化外,其他字符串会遵循 json 的要求,不包含控制字符和 \ "(替换为转义字符或十六进制) 以前写过『用正则去除 不规则 json 中的末项逗号』(如:[1, 2, 3,]),想着拿来改改就好 发现功力不够,必须要用到 (?>...) 特性,来防止回溯(即,碰到 \ 就一定要继续匹配后面的转义字符) 但这也导致 Javascript 、Golang 、Python 3.10 及以下版本 无法使用( Python 3.11 开始支持了) 正则:"((?:(?>\\?).)*?)"\s*(:)|("(?:\\?.)*?") 替换:$1$2$3 引擎:PCRE 『例子( v 站排版原因,行首有若干全角空格,但不影响)』 [ "\"fake_key\": value", 123, true, false, null, { "key1" : "\n\\\":,]:\\", "key2" : "\n\\\":,}:\\", }, ] 『替换后』 [ "\"fake_key\": value", 123, true, false, null, { key1: "\n\\\":,]:\\", key2: "\n\\\":,}:\\", }, ] |
31 wxf666 2022-09-02 00:38:13 +08:00 @mylifcc 28 楼有个小地方写错了, {k: f'\\{v}' for k, v in zip('\b\t\n\f\r\\"', 'btnfr"\\')} 改成 {k: f'\\{v}' for k, v in zip('\b\t\n\f\r\\"', 'btnfr\\"')} |
33 js8510 2022-09-02 01:59:34 +08:00 ``` >>> class Key: ... def __repr__(self): ... return "Key" ... >>> >>> >>> >>> m={Key(), 1} >>> m {1, Key} ``` 这样不就好了?? |
34 gongshuiwen 2022-09-02 10:21:17 +08:00 使用非字符串对象作为键就会输出该格式,例如: class City: pass city = City() print({city: "beijing"}) 输出结果为:{<__main__.City object at 0x000001CE970BB608>: 'beijing'} 上面为对象默认的字符串表示形式,可以使用 __repr__ 方法改变对象的字符串表示形式: class City: def __repr__(self): return 'city' city = City() print({city: "beijing"}) 输入结果为:{city: 'beijing'} 所以字典中不带引号的键说明是一个非字符串对象作为的键吧。 |
35 xiaochun41 2022-09-02 10:44:07 +08:00 楼上和楼上的楼上的分析可以借鉴,python 里面字典打印的时候调用的是 dict 的这个方法 __repr__ ,单说 key 的话 也是调用的 key 的类型对应的 __repr__ 方法。 所以就是两个思路: 1 . 继承 dict ,重新定义一个自己的字典类,重新实现 __repr__ 2 . 针对特定的 key ,重新实现 key 的 __repr__方法 |
36 pjxxcc 2022-09-02 11:06:53 +08:00 用数字作为 key ,就不会带引号哦 比如: >>> d = {1: 'yi', 'a': "A"} >>> d {1: 'yi', 'a': 'A'} >>> print(d) {1: 'yi', 'a': 'A'} |
37 stonesirsir 2022-12-30 16:18:55 +08:00 遍历字典,然后用字符串打印出来吧 |