2012-12-28 46 views
1

字典鍵上找到如何檢查字符串列表是行內這個偉大的答案 How to check if a line has one of the strings in a list?的Python:如果行

但是試着用鑰匙類似的事情在一個字典似乎沒有做這份工作對我來說:

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()給了我一個數組,而不是名單。但還沒有想出如何將它轉換..

+5

我剛跑過這個,testCounter是2,而不是377。如果你得到意想不到的比賽,我會建議打印出當前的比賽數據。 – alexp

+1

'countryCode in currency'在功能上等同於'currency.keys()'中的'countryCode'。 –

回答

5

變化:

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

到:

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

您的原始代碼使用生成器表達式,而(我認爲)您的意圖是列表理解。 見:Generator Expressions vs. List Comprehension

UPDATE: 我發現,使用與pylab一個IPython的解釋進口,我得到了相同的結果,你沒有(377個計數與預期的2)。我意識到這個問題是,'任何'是來自numpy包,這意味着要在一個數組上工作。 接下來,我加載了一個沒有pylab的ipython解釋器,以至於'any'來自內建的。在這種情況下,您的原始代碼有效。 因此,如果您使用IPython的解釋型:

help(any) 

,並確保它是內置的模塊。如果是這樣你的原代碼應該可以正常工作

+0

這兩者之間絕對沒有區別,只是第二個使用熱切評估來不必要地查找所有匹配。第一場比賽將在第一場比賽後停止,因爲不需要其他比賽來讓'any'返回true。 –

+0

好的,你說得對。現在我需要理解爲什麼第二個人會給出預期的結果,而第一個不會。謝謝。 – ljk07

+0

我在使用IPython ;-)非常感謝! – Norfeldt

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 

如果你只在什麼碼都存在興趣,不關心的特定條目,您可以使用交集:

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

print codes & frozenset(currencies)