我有一个使用pformat()
将字典转换为字符串的函数(无关:字符串稍后会在write()
文件中插入.py
)。
所以MY_DCT = {1: 11, 2: 22, 3: 33}
会变成这样的字符串:
MY_DCT = {
1: 11,
2: 22,
3: 33}
该功能有2个要求:
这是功能:
import pprint
def f(obj_name, obj_body_as_dct):
body = '{\n' + pprint.pformat(obj_body_as_dct, indent=4, width=1)[1:]
name_and_equal_sign = obj_name + ' = '
return name_and_equal_sign + body + '\n\n'
d = {1: 11, 2: 22, 3: 33}
print(f('MY_DCT', d))
如果indent=0
我收到此字符串:
MY_DCT = {
1: 11,
2: 22,
3: 33}
如果indent=4
我收到此字符串:
MY_DCT = {
1: 11,
2: 22,
3: 33}
我检查了pformat()
的{{3}},但我无法弄清楚如何在每一行上显示正确数量的空格。
我知道我可以使用replace()
,+' '
等来修复字符串,但我想知道这个额外的空格来自哪里,如果我可以通过正确设置参数来摆脱它(如果可能的话,那就是)。
注意:如果有更好的方法来实现上述目标,请告诉我。
答案 0 :(得分:2)
indent
中pformat
的默认值为1,因此键在另一个下方显示为一个。
例如,pformat(d, indent=0, width=1)
会产生此字符串:
{1: 11,
2: 22,
3: 33}
indent=1
:
{1: 11,
2: 22,
3: 33}
和indent=2
:
{ 1: 11,
2: 22,
3: 33}
第一行总是少一个空格。
由于目标是在第一行之后显示dict元素,并且所有元素都缩进4个空格,因此在第一个元素之前添加单个空格并使用indent=4
将对某些dicts起作用(如@所示)逻辑)。
然而像d = {1: {'a': 1, 'b': 2}, 2: 22, 3: 33}
这样的词汇会显得相当难看,因为indent
会影响深度大于1的词典的出现:
MY_DCT = {
1: { 'a': 1,
'b': 2},
# ^
# |
# ugly
2: 22,
3: 33}
最吸引人的解决方案(对于我正在处理的数据)保留indent=1
并为第一个元素添加3个空格,其余为4个空格。
def f(obj_name, given_dct):
"""
Converts given dct (body) to a pretty formatted string.
Resulting string used for file writing.
Args:
obj_name: (str) name of the dict
Returns:
(str)
"""
string = pp.pformat(given_dct, width=1)[1:]
new_str = ''
for num, line in enumerate(string.split('\n')):
if num == 0:
# (pprint module always inserts one less whitespace for first line)
# (indent=1 is default, giving everything one extra whitespace)
new_str += ' '*4 + line + '\n'
else:
new_str += ' '*3 + line + '\n'
return obj_name + ' = {\n' + new_str
s = f(obj_name='MY_DCT', given_dct=d)
导致此字符串:
MY_DCT = {
1: {'a': 'aa',
'b': [1,
2,
3]},
2: 22,
3: 33}
答案 1 :(得分:1)
参数不是打印的问题。添加换行符('\n'
)时会出现此问题。从这个例子可以看出:
import pprint
def f(obj_name, obj_body_as_dct):
body = '{' + pprint.pformat(obj_body_as_dct, indent=4, width=1, depth=1)[1:]
name_and_equal_sign = obj_name + ' = ' + '\n'
return '"""' + name_and_equal_sign + body + '"""' + '\n\n'
d = {1: 11, 2: 22, 3: 33}
print(f('MY_DCT', d))
输出:
"""MY_DCT =
{ 1: 11,
2: 22,
3: 33}"""
新行,以及在第一行打印中添加“{
”是为什么只有输出的第一行似乎偏移了一小块空间。
更新#1 :
在对这些值进行一些修补之后,我能够匹配您想要的输出:
import pprint
def f(obj_name, obj_body_as_dct):
body = pprint.pformat(obj_body_as_dct, indent=4, width=1, depth=1)[1:]
name_and_equal_sign = obj_name
return '"""' + name_and_equal_sign + ' = ' + '{' + '\n ' + body +'"""' + '\n\n'
# ^ I added a space in this newline
d = {1: 11, 2: 22, 3: 33}
print(f('MY_DCT', d))
以上代码输出:
"""MY_DCT = {
1: 11,
2: 22,
3: 33}"""
所以,实质上,你只需要换行符中的一个空格(在代码中显示)。
更新#2 :
在评论中提出您的建议:
试试这个:
print(pp.pformat({1:11, 2:22, 3:33}, indent=0, width=1))
, 缩进从0到2.你会注意到,它少了一个 第一行的空格。这是pformat()
的构建方式。 - @ user 5061
我试过了:
import pprint as pp
for i in range(0,3):
print(pp.pformat({1:11, 2:22, 3:33}, indent=i, width=1))
它给了我这个输出:
{1: 11, #Indent = 0 Each entry (except 1) is indented by 0 spaces, because the "{" operator is in the way.
2: 22,
3: 33}
{1: 11, #Indent = 1 Each entry is indented by 1 spaces
2: 22,
3: 33}
{ 1: 11, #Indent = 2 Each entry is indented by 2 spaces
2: 22,
3: 33}
正如您所看到的,问题仍然存在:“{
”
如果那不存在,则缩进甚至会持续。编码函数pformat()
以调整该字符。
答案 2 :(得分:0)
Logic's answer让您了解为什么您有缩进问题。然而,作为( IMO )更简洁的方法,您可以使用json
。此输出假设元素表示字典元素:
import json
obj_name = 'MY_DCT = '
obj_body_as_dct = {1: 11, 2: 22, 3: 33}
stringy = "\"\"\"" + obj_name + "{" \
+ str(json.dumps(obj_body_as_dct, indent=4, separators=(',', ': ')))[1:] + "\"\"\""
print(stringy)
<强>输出:强>
"""MY_DCT = {
"1": 11,
"2": 22,
"3": 33
}"""