或者说这是一个什么样的格式?
比如
{
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 1
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
遍历字典,然后用字符串打印出来吧
|