这是一个具体的例子:
my_dict={k:int(encoded_value)
for (k,encoded_value) in
[encoded_key_value.split('=') for encoded_key_value in
many_encoded_key_values.split(',')]}
问题是关于内部列表[],可以避免,例如:
# This will not parse
my_dict={k:int(encoded_value)
for (k,encoded_value) in
encoded_key_value.split('=') for encoded_key_value in
many_encoded_key_values.split(',')}
...,这是无效的语法:
NameError: name 'encoded_key_value' is not defined
示例数据:aa=1,bb=2,cc=3,dd=4,ee=-5
答案 0 :(得分:5)
如前所述,生成器表达式将增强您的方法,避免创建内部列表。但是使用re.findall()
函数获得所需结果的方法较短:
result = {k:int(v) for k,v in re.findall(r'(\w+)=([^,]+)', many_encoded_key_values)}
print(result)
输出:
{'dd': 4, 'aa': 1, 'bb': 2, 'ee': -5, 'cc': 3}
替代方法是使用re.finditer()
函数返回'callable_iterator'
实例:
result = {m.group(1):int(m.group(2)) for m in re.finditer(r'(\w+)=([^,]+)', many_encoded_key_values)}
答案 1 :(得分:3)
您可以通过使用中间生成器表达式来避免创建中间列表:
.split
语法方面,这几乎是一样的;不是首先生成中间列表然后使用元素,而是动态消耗元素。
使这个过于冗长,您可以使用数据管道'由发电机组成:
split
(遗憾的是func receiptValidation() {
// appStoreReceiptURL still says sandboxReceipt
if let appStoreReceiptURL = Bundle.main.appStoreReceiptURL,
FileManager.default.fileExists(atPath: appStoreReceiptURL.path) {
do {
let receiptData = try Data(contentsOf: appStoreReceiptURL, options: .alwaysMapped)
let receiptString = receiptData.base64EncodedString(options: [])
let dict = ["receipt-data" : receiptString, "password" : iTunesMasterAppSecret] as [String : Any]
do {
let jsonData = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted)
var receiptUrl:String
if (liveMode) {
receiptUrl = "https://buy.itunes.apple.com/verifyReceipt"
}
else {
receiptUrl = "https://sandbox.itunes.apple.com/verifyReceipt"
}
// appStoreReceiptURL still says sandboxReceipt
if let sandboxURL = Foundation.URL(string:receiptUrl) {
var request = URLRequest(url: sandboxURL)
request.httpMethod = "POST"
request.httpBody = jsonData
let session = URLSession(configuration: URLSessionConfiguration.default)
let task = session.dataTask(with: request) {
if let receivedData = data,
let httpResponse = response as? HTTPURLResponse,
error == nil,
httpResponse.statusCode == 200 {
do {
if let jsonResponse = try JSONSerialization.jsonObject(with: receivedData, options: JSONSerialization.ReadingOptions.mutableContainers) as? Dictionary<String, AnyObject>
没有返回生成器,因此考虑节省空间这没什么用处......对于处理大文件这样的事情可能会派上用场。)
找到this answer,其21007 -- This receipt is from the test environment, but it was sent to the production environment for verification. Send it to the test environment instead.
作为迭代器。以防万一......
答案 2 :(得分:1)
FWIW,这是一种功能性方法:
def convert(s):
k, v = s.split('=')
return k, int(v)
d = dict(map(convert, data.split(',')))
print(d)
<强>输出强>
{'aa': '1', 'bb': '2', 'cc': '3', 'dd': '4', 'ee': '-5'}
答案 3 :(得分:0)
一个简单而紧凑的变体,与您原来的尝试非常接近:
d = {v.strip(): int(i) for s in data.split(',') for v, i in (s.split('='),)}
唯一的额外&#39;技巧&#39;是将s.split('=')
包装在元组内(用括号括起来(s.split('='),)
),以便在同一split
次迭代中获取for
的两个元素。其余的很简单。