在python中,我们可以使用str.format
来构造这样的字符串:
string_format + value_of_keys = formatted_string
例如:
FMT = '{name:} {age:} {gender}' # string_format
VoK = {'name':'Alice', 'age':10, 'gender':'F'} # value_of_keys
FoS = FMT.format(**VoK) # formatted_string
在这种情况下,formatted_string = 'Alice 10 F'
我只是想知道是否有办法从value_of_keys
和formatted_string
获取string_format
?它应该是函数Fun
和
VoK = Fun('{name:} {age:} {gender}', 'Alice 10 F')
# the value of Vok is expected as {'name':'Alice', 'age':10, 'gender':'F'}
有没有办法获得此功能Fun
?
增加:
我想说,'{name:} {age:} {gender}'
和'Alice 10 F'
只是一个最简单的例子。现实情况可能更困难,space
分隔符可能不存在。
从数学上讲,大多数情况都不可逆,例如:
FMT = '{key1:}{key2:}'
FoS = 'HelloWorld'
VoK
可以是以下任何一个:
{'key1':'Hello','key2':'World'}
{'key1':'Hell','key2':'oWorld'}
....
因此,为了明确定义这个问题,我想补充两个条件:
1. There are always delimiters between two keys
2. All delimiters are not included in any value_of_keys.
在这种情况下,这个问题是可以解决的(在数学上说):)
显示输入和预期输出的另一个示例:
In '{k1:}+{k2:}={k:3}', '1+1=2' Out {'k1':1,'k2':2, 'k3':3}
In 'Hi, {k1:}, this is {k2:}', 'Hi, Alice, this is Bob' Out {'k1':'Alice', 'k2':'Bob'}
答案 0 :(得分:1)
获取新字符串后,python无法确定如何创建格式化字符串。
例如:一旦您的格式"{something} {otherthing}"
包含空格值并且您获得了所需的字符串,就无法区分带空格的单词是{something}
还是{otherthing}
<的一部分/ p>
但是,如果您了解新字符串的格式并且结果一致,则可能会使用一些黑客。
例如,在您给出的示例中:如果您确定您的单词后跟空格,然后是数字,然后是空格,然后是单词,那么您可以使用以下正则表达式来提取值:< / p>
>>> import re
>>> my_str = 'Alice 10 F'
>>> re.findall('(\w+)\s(\d+)\s(\w+)', my_str)
[('Alice', '10', 'F')]
为了从中获取所需的dict
,您可以将逻辑更新为:
>>> my_keys = ['name', 'age', 'gender']
>>> dict(zip(my_keys, re.findall('(\w+)\s(\d+)\s(\w+)', my_str)[0]))
{'gender': 'F', 'age': '10', 'name': 'Alice'}
答案 1 :(得分:1)
此代码为所有值生成字符串,但它会将字符串拆分为其组成组件。它取决于分隔符是空格,而不是包含空格的值。如果任何值包含空格,这将成为一个更难的问题。
>>> delimiters = ' '
>>> d = {k: v for k,v in zip(('name', 'age', 'gender'), 'Alice 10 F'.split(delimiters))}
>>> d
{'name': 'Alice', 'age': '10', 'gender': 'F'}
答案 2 :(得分:1)
您确实可以这样做,但格式字符串略有不同,称为正则表达式。
以下是您的操作方法:
import re
# this is how you write your "format"
regex = r"(?P<name>\w+) (?P<age>\d+) (?P<gender>[MF])"
test_str = "Alice 10 F"
groups = re.match(regex, test_str)
现在您可以使用groups
访问字符串的所有组件:
>>> groups.group('name')
'Alice'
>>> groups.group('age')
'10'
>>> groups.group('gender')
'F'
正则表达式是一件非常酷的事情。我建议你在网上了解更多。
答案 3 :(得分:1)
根据您的要求,我有一个解决方案。 这个解决方案的概念是:
import re
from collections import OrderedDict
def Func(data, delimiters, delimiter):
# change all delimiters to delimiter
for d in delimiters:
data[0] = data[0].replace(d, delimiter)
data[1] = data[1].replace(d, delimiter)
# get keys with '{}'
keys = data[0].split(delimiter)
# if string starts with delimiter remove first empty element
if keys[0] == '':
keys = keys[1:]
# get keys without '{}'
p = re.compile(r'{([\w\d_]+):*.*}')
keys = [p.match(x).group(1) for x in keys]
# get values
vals = data[1].split(delimiter)
# if string starts with delimiter remove first empty element
if vals[0] == '':
vals = vals[1:]
# pack to a dict
result_1 = dict(zip(keys, vals))
# if you need Ordered Dict
result_2 = OrderedDict(zip(keys, vals))
return result_1, result_2
用法:
In_1 = ['{k1}+{k2:}={k3:}', '1+2=3']
delimiters_1 = ['+', '=']
result = Func(In_1, delimiters_1, delimiters_1[0])
# Out_1 = {'k1':1,'k2':2, 'k3':3}
print(result)
In_2 = ['Hi, {k1:}, this is {k2:}', 'Hi, Alice, this is Bob']
delimiters_2 = ['Hi, ', ', this is ']
result = Func(In_2, delimiters_2, delimiters_2[0])
# Out_2 = {'k1':'Alice', 'k2':'Bob'}
print(result)
输出:
({'k3': '3', 'k2': '2', 'k1': '1'},
OrderedDict([('k1', '1'), ('k2', '2'), ('k3', '3')]))
({'k2': 'Bob', 'k1': 'Alice'},
OrderedDict([('k1', 'Alice'), ('k2', 'Bob')]))
答案 4 :(得分:1)
我写了一个功能,似乎有用:
classifier = Sequential()
classifier.add(Convolution2D(32, (3,3), input_shape = (64, 64, 3), activation='relu'))
classifier.add(MaxPool2D(pool_size = (2,2)))
classifier.add(Convolution2D(32, (3,3), activation='relu'))
classifier.add(MaxPool2D(pool_size = (2,2)))
classifier.add(Convolution2D(32, (3,3), activation='relu'))
classifier.add(MaxPool2D(pool_size = (2,2)))
classifier.add(Convolution2D(32, (3,3), activation='relu'))
classifier.add(MaxPool2D(pool_size = (2,2)))
classifier.add(Flatten())
classifier.add(Dense(units=128, activation='relu'))
classifier.add(Dropout(rate = 0.25))
classifier.add(Dense(units=128, activation='relu'))
classifier.add(Dropout(rate = 0.25))
classifier.add(Dense(units=1, activation='sigmoid'))
classifier.compile(optimizer = 'sgd', loss = 'binary_crossentropy', metrics=['accuracy'])
用法:
eg1:
import re
def Fun(fmt,res):
reg_keys = '{([^{}:]+)[^{}]*}'
reg_fmts = '{[^{}:]+[^{}]*}'
pat_keys = re.compile(reg_keys)
pat_fmts = re.compile(reg_fmts)
keys = pat_keys.findall(fmt)
lmts = pat_fmts.split(fmt)
temp = res
values = []
for lmt in lmts:
if not len(lmt)==0:
value,temp = temp.split(lmt,1)
if len(value)>0:
values.append(value)
if len(temp)>0:
values.append(temp)
return dict(zip(keys,values))
EG2:
fmt = '{k1:}+{k2:}={k:3}'
res = '1+1=2'
print Fun(fmt,res)
>>>{'k2': '1', 'k1': '1', 'k': '2'}
eg3:
fmt = '{name:} {age:} {gender}'
res = 'Alice 10 F'
print Fun(fmt,res)
>>>
答案 5 :(得分:0)
试试这个:
import re
def fun():
k = 'Alice 10 F'
c = '{name:} {age:} {gender}'
l = re.sub('[:}{]', '', c)
d={}
for i,j in zip(k.split(), l.split()):
d[j]=i
print(d)
您可以根据需要更改有趣参数并将其分配给变量。它接受您想要提供的相同字符串。并给出这样的字典:
{'name': 'Alice', 'age': '10', 'gender': 'F'}
答案 6 :(得分:0)
我建议使用**kwargs
解决此问题的另一种方法,例如......
def fun(**kwargs):
result = '{'
for key, value in kwargs.iteritems():
result += '{}:{} '.format(key, value)
# stripping the last space
result = result[:-1]
result += '}'
return result
print fun(name='Alice', age='10', gender='F')
# outputs : {gender:F age:10 name:Alice}
注意: kwargs 不是有序的dict,只会将参数的顺序保持在Python的3.6版本。如果您需要保留订单,那么构建解决方案很容易。