1

找到了关于如何检查字符串列表是否在一行中的好答案 如何检查一行是否包含 列表中的一个字符串?

但是尝试用字典中的键做类似的事情似乎对我没有用:

import urllib2

url_info = urllib2.urlopen('http://rss.timegenie.com/forex.xml')
currencies = {"DKK": [], "SEK": []}
print currencies.keys()
testCounter = 0

for line in url_info:
    if any(countryCode in line for countryCode in currencies.keys()):
        testCounter += 1
    if "DKK" in line or "SEK" in line:
        print line
print "testCounter is %i and should be 2 - if not debug the code" % (testCounter)

输出:

['SEK', 'DKK']
<code>DKK</code>
<code>SEK</code>
testCounter is 377 and should be 2 - if not debug the code

认为也许我的问题是因为.keys()给了我一个数组而不是一个列表..但还没有弄清楚如何转换它..

4

2 回答 2

5

改变:

any(countryCode in line for countryCode in currencies.keys())

到:

any([countryCode in line for countryCode in currencies.keys()])

您的原始代码使用生成器表达式,而(我认为)您的意图是列表理解。请参阅:生成器表达式与列表理解

更新:我发现使用导入了 pylab 的 ipython 解释器得到了与您相同的结果(377 个计数与预期的 2 个计数)。我意识到问题在于“任何”来自 numpy 包,该包旨在处理数组。接下来,我加载了一个没有 pylab 的 ipython 解释器,这样 'any' 来自builtin。在这种情况下,您的原始代码有效。因此,如果您使用 ipython 解释器类型:

help(any)

并确保它来自内置模块。如果是这样,您的原始代码应该可以正常工作。

于 2012-12-28T15:13:40.640 回答
1

这不是检查 xml 文件的好方法。

  1. 它很慢。您正在进行潜在的 N*M 子字符串搜索,其中 N 是行数,M 是键数。
  2. XML 不是面向行的文本格式。您的子字符串搜索也可以找到属性名称或元素名称,这可能不是您想要的。如果 XML 文件碰巧将其所有元素放在没有空格的一行上(这对于机器生成和处理的 XML 很常见),那么您得到的匹配项将比您预期的要少。

如果您有面向行的文本输入,我建议您从键列表中构造一个正则表达式:

import re
linetester = re.compile('|'.join(re.escape(key) for key in currencies))

for match in linetester.finditer(entire_text):
    print match.group(0)

#or if entire_text is too long and you want to consume iteratively:

for line in entire_text:
        for match in linetester.find(line):
            print match.group(0)

然而,既然你有 XML,你应该使用一个实际的 XML 处理器:

import xml.etree.cElementTree as ET

for elem in forex.findall('data/code'):
    if elem.text in currencies:
        print elem.text

如果您只对存在的代码感兴趣并且不关心您可以使用 set intersection 的特定条目:

codes = frozenset(e.text for e in forex.findall('data/code'))

print codes & frozenset(currencies)
于 2012-12-28T15:47:16.357 回答