4

我有一个看起来像这样的字典列表:

serv=[{'scheme': 'urn:x-esri:specification:ServiceType:DAP',
  'url': 'http://www.esrl.noaa.gov/psd/thredds/dodsC/Datasets/air.mon.anom.nobs.nc'},
 {'scheme': 'urn:x-esri:specification:ServiceType:WMS',
  'url': 'http://www.esrl.noaa.gov/psd/thredds/wms/Datasets/air.mon.anom.nobs.nc?service=WMS&version=1.3.0&request=GetCapabilities'},
 {'scheme': 'urn:x-esri:specification:ServiceType:WCS',
  'url': 'http://ferret.pmel.noaa.gov/geoide/wcs/Datasets/air.mon.anom.nobs.nc?service=WCS&version=1.0.0&request=GetCapabilities'}]

我想找到对应的 URL,ServiceType:WMS这意味着url从这个列表中找到 key 的值,其中schemekey 具有 value urn:x-esri:specification:ServiceType:WMS

所以我有这个工作:

for d in serv:
    if d['scheme']=='urn:x-esri:specification:ServiceType:WMS':
        url=d['url']
print url

产生

http://www.esrl.noaa.gov/psd/thredds/wms/Datasets/air.mon.anom.nobs.nc?service=WMS&version=1.3.0&request=GetCapabilities

但是我刚刚看了Raymond Hettinger 的 PyCon 演讲,最后他说如果你可以把它说成一个句子,它应该用一行 Python 来表达。

那么有没有一种更漂亮、更惯用的方式来实现相同的结果,也许只需要一行 Python 代码?

谢谢,丰富

4

5 回答 5

2

如果您只对一个 URL 感兴趣,那么您可以构建一个生成器,servnext在未找到匹配项的情况下使用默认值,例如:

url = next((dct['url'] for dct in serv if dct['scheme'] == 'urn:x-esri:specification:ServiceType:WMS'), 'default URL / not found')
于 2013-04-04T00:40:37.603 回答
2

您列出的serv数组看起来像一个到 URL 的字典映射方案,但它不是这样表示的。不过,您可以轻松地将其转换为dictusing 列表推导,然后使用普通的字典查找:

url = dict([(d['scheme'],d['url']) for d in serv])['urn:x-esri:specification:ServiceType:WMS']

当然,您可以保存字典版本以供将来使用(以使用两行为代价):

servdict = dict([(d['scheme'],d['url']) for d in serv])
url = servdict['urn:x-esri:specification:ServiceType:WMS']
于 2013-04-04T01:01:23.083 回答
2

我会将其分成两行,以将目标与 url 检索分开。这是因为您的目标可能会随着时间而改变,所以这不应该是硬连线的。单行代码如下。

我会使用in而不是==因为我们想搜索所有这种类型的方案。这增加了更多的灵活性和可读性,假设这也不会捕获其他不需要的方案。但从描述来看,这是所需的功能。

target = "ServiceType:WMS"
url = [d['url'] for d in serv if target in d['scheme']]

另外,请注意,这在所有情况下都会返回一个列表,以防有多个匹配项,因此您必须url在使用它的代码中循环。

于 2013-04-05T15:10:52.113 回答
1

这个怎么样?

urls = [d['url'] for d in serv if d['scheme'] == 'urn:x-esri:specification:ServiceType:WMS']

print urls # ['http://www.esrl.noaa.gov/psd/thredds/wms/Datasets/air.mon.anom.nobs.nc?service=WMS&version=1.3.0&request=GetCapabilities']

它在做你的代码正在做的同样的事情,在哪里d['url']被追加到列表中——urls如果它们以WMS

你甚至可以添加一个 else 子句:

urls = [i['url'] for i in serv if i['scheme'].endswith('WMS') else pass]
于 2013-04-04T00:32:30.253 回答
1

我一直在尝试将更多的函数式编程融入到我自己的工作中,所以这里有一个非常简单的函数式方法:

needle='urn:x-esri:specification:ServiceType:WMS'
url = filter( lambda d: d['scheme']==needle, serv )[0]['url']

filter将返回布尔值和要过滤的列表的函数作为参数。它返回一个元素列表,这些元素True在传递给布尔返回函数时返回(在本例中是lambda我动态定义的)。因此,要最终获得 url,我们必须获取filter返回列表的第 0 个元素。由于那是包含我们想要的 url 的 dict,我们可以['url']在整个表达式的末尾添加标签以获取相应的字典条目。

于 2013-04-04T00:45:35.317 回答