2016-04-28 273 views
-1

我想创建一个计数器,找到它需要从一个文件计数,它应该从另一个文件计数。它打开file1,发现一个城市及其人口以短划线分开,file2显示城市名称和犯罪分隔的罪行。当我对城市名称进行硬编码时效果不错,但是当我尝试使用if循环来查找城市名称时,它会发现第一个城市在犯罪报告中出现了多少次,但之后没有更多。请帮助嵌套for循环只迭代一次

for line in file1: 
    dash = line.find("-") 
    variableCity = line[:dash] 
    cityPop = line[dash + 1:] 
    crimeCounter = 0 
    for crime in file2: 
     x = crime[:dash] 
     if x == variableCity: 
      crimeCounter += 1 
    print("{} which has a population of {} has {} reported crimes".format(variableCity, cityPop, crimeCounter)) 

这是我的代码

文件1:

Bothell-89232 
Kent-97232 
Tacoma-89333 
Renton-98632 
Redmond-64789 
Seattle-76978 

文件2:

Kent-Theft 
Tacoma-Break In 
Seattle-Break In 
Tacoma-Auto Break In 
Federal Way-Auto Break In 
Kent-Break In 
Tacoma-Auto Break In 
Federal Way-Auto Break In 
Kent-Mugging 
Kent-Break In 
Federal Way-Break In 
Renton-Break In 
Renton-Auto Theft 
Tacoma-Mugging 
Seattle-Theft 
Auburn-Auto Theft 
Renton-Theft 
Tacoma-Auto Theft 
Kent-Mugging 
Seattle-Auto Break In 
Tacoma-Theft 
Kent-Auto Theft 
Seattle-Break In 
Auburn-Mugging 
Tacoma-Mugging 
Auburn-Auto Theft 
Auburn-Auto Theft 
Seattle-Auto Theft 
Federal Way-Mugging 
Kent-Mugging 
Renton-Auto Theft 
Tacoma-Mugging 
Auburn-Theft 
Seattle-Auto Break In 
Auburn-Mugging 
Seattle-Theft 
Auburn-Theft 
Auburn-Auto Break In 
Federal Way-Auto Break In 
Seattle-Break In 
Kent-Theft 
Seattle-Auto Break In 
Federal Way-Auto Break In 
Kent-Auto Break In 
Seattle-Auto Break In 
Renton-Auto Break In 
Kent-Auto Break In 
Renton-Break In 
Federal Way-Mugging 
Seattle-Mugging 
Renton-Mugging 
Renton-Auto Break In 
Tacoma-Mugging 
Tacoma-Auto Theft 
Seattle-Auto Break In 
Kent-Auto Theft 
Kent-Auto Theft 
Federal Way-Mugging 
Tacoma-Auto Theft 
Federal Way-Theft 
Tacoma-Auto Theft 
Renton-Auto Theft 
Seattle-Theft 
Seattle-Auto Break In 
Tacoma-Mugging 
Tacoma-Auto Theft 
Seattle-Break In 
Federal Way-Theft 
Seattle-Auto Break In 
Auburn-Auto Break In 
Auburn-Auto Break In 
Tacoma-Break In 
Seattle-Mugging 
Renton-Theft 
Auburn-Theft 
Renton-Theft 
Seattle-Auto Theft 
Auburn-Mugging 
Seattle-Break In 
Kent-Mugging 
Kent-Break In 
Federal Way-Break In 
Federal Way-Auto Theft 
Auburn-Theft 
Tacoma-Theft 
Kent-Auto Break In 
Auburn-Auto Theft 
Seattle-Mugging 
Kent-Theft 
Kent-Mugging 
Kent-Auto Break In 
Seattle-Theft 
Tacoma-Auto Theft 
Renton-Theft 
Renton-Break In 
Auburn-Break In 
Renton-Mugging 
Renton-Mugging 
Tacoma-Break In 

请注意,在每个文件出现在新行

下一城
+2

file1和file2是否只有一行,或者每个城市都占用一行? –

+0

请正确缩进您的代码。 – niyasc

+0

这里没有嵌套的'if','if'不是循环。 – tripleee

回答

1

看起来像哟ü错过发现在这片划线的位置:

for crime in file2: 
    x = crime[:dash] 

它不应该是:

for crime in file2: 
    dash = crime.find("-") 
    x = crime[:dash] 

无论采用哪种方式比较正确的解决方案应该是这样的:

for line in file1: 
    parsed = line.split("-") 
    variableCity = parsed[0] 
    cityPop = parsed[1][:-1] 

    file2 = open("file2.txt") 
    crimeCounter = 0 
    for crime in file2: 
     c = crime.split("-") 
     if c[0] == variableCity: 
      crimeCounter += 1 

    print("{} which has a population of {} has {} reported crimes".format(variableCity, cityPop, crimeCounter)) 

然而,更多的最优解决方案应该通过两遍,第一遍我们正在阅读城市信息来绘制地图并且增加犯罪报告:

citiesPop = {} 
citiesCrime = {} 

for line in file1: 
    parsed = line.split("-") 
    city = parsed[0] 
    cityPop = parsed[1][:-1] 
    citiesPop[city] = cityPop 
    citiesCrime[city] = 0 

for crime in file2: 
    city = crime.split("-")[0] 
    if city in citiesCrime: 
     citiesCrime[city] += 1 

for city in citiesPop.keys(): 
    print("{} which has a population of {} has {} reported crimes".format(city, citiesPop[city], citiesCrime[city])) 
+0

我使用第一个循环中找到的短划线,因为我正在寻找城市,所以城市名称的长度应该相同。另外我的问题是,第二个循环只迭代一次 – syanh7

+0

@ syanh7请参阅编辑解决方案,随时提问 –

+0

谢谢!我现在要仔细看看它 – syanh7

0

该代码似乎是正确的,我猜你的file1file2有问题。您可以检查这两个变量或显示有关如何获得file1file2

0

如果您使用的文件中,你有一个像

file1=open('file1') 
file2=open('file2') 

你会行代码处理

即某处前面的代码在第二次和后续搜索之前需要回到file2的开头

例如

线

for crime in file2: 

之前或打印计数器行之后添加行

file2.seek(0) 

否则文件指针留在最后如果文件,你不会从它得到任何“罪行”。有点像在重放之前不得不倒带。

我相信一旦将文件内容读入变量会更有效,然后这个问题不会发生,但我猜如果它们是小文件,可能没有太大的区别。如果它们是大文件,内存使用可能会阻止你阅读它们,但我怀疑它们是那么大。

+0

感觉像我一样是一个答案,因为他确实使用这种方法,哦,没什么大不了的,我只是想超过50点,所以我可以添加评论;-) @matthias命中它好。 – NanoTera

+0

是啊你的是最简单的修复!谢谢 – syanh7

+0

我自己是新手,但我认为你@ syanh7应该打勾或以某种方式标记它,我还没有问过任何问题,所以我自己也不确定。我甚至不确定它是否适合我“要求”或评论如此。 – NanoTera

0

让我提供一些关于如何清理代码的建议,以便我们可以看到错误的位置,以及一些常规的python调试技巧。

对于第一个文件,考虑使用variableCity, cityPop = line.split('-')以简化解析逻辑。 Simpler logic -> less bugs是我的经验法则。事情是这样的:

for line in file1: 
    variableCity, cityPop = line.split('-') 

或者你甚至可以把它放进自己的字典马上:

city_pops = dict(line.split('-') for line in file1) 

现在你甚至不需要你的窝循环for!这有几个优点。最重要的是,现在您可以在交互式解释器中检查数据结构,看看它是否正确。

>>> city_pops 
{'Tacoma': '89333', 'Redmond': '64789', 'Kent': '97232', 'Seattle': '76978', 'Renton': '98632', 'Bothell': '89232'} 

如果数据结构太大,请尝试只检查几个条目。您还可以检查多少个条目len(city_pops)

伟大的,分而治之!现在,您已将第一个文件排除在外,并且您知道它正在被正确解析,那么我们可以转到第二个文件。

让我们在这里再次使用破折号技术。另外,由于您正在计数,我会建议使用未使用的内置集合Counter

如果你想仅计算所有条目,你可以这样做:

from collections import Counter 
crime_rate = Counter(line.split('-')[0] for line in file2) 

您可以检查一下这个看起来像在解释一遍,以确保你在正确的轨道上:

>>> crime_rate 
Counter({'Seattle': 21, 'Tacoma': 18, 'Kent': 18, 'Auburn': 15, 'Renton': 15, 'Federal Way': 12}) 

现在你只需要过滤掉你不感兴趣的城市确保每个城市的名字是从早期在city_pops字典中的键:

crime_rate = Counter(line.split('-')[0] for line in file2 
        if line.split('-')[0] in city_pops.keys()) 

最终结果:

故事
>>> crime_rate 
Counter({'Seattle': 21, 'Tacoma': 18, 'Kent': 18, 'Renton': 15}) 

道德的,不,如果你不需要嵌套循环。它使调试更加困难,并且可能增加程序的计算复杂性。也可以自由使用string.split()方法和Counter类。最后,理解和生成器表达式总是比for循环更好。

基本上那么你的程序可以归结为两行:

city_pops = dict(line.split('-') for line in file1) 
crime_rate = Counter(line.split('-')[0] for line in file2 
        if line.split('-')[0] in city_pops.keys()) 
0

我想我得到了它 我所做的就是添加 file2.seek() 因此,新的代码是

for line in file1: 
    dash = line.find("-") 
    variableCity = line[:dash] 
    cityPop = line[dash + 1:] 
    crimeCounter = 0 
    file2.seek(0) 
    for crime in file2: 
     x = crime[:dash] 
     if x == variableCity: 
      crimeCounter += 1 
    print("{} which has a population of {} has {} reported crimes".format(variableCity, cityPop, crimeCounter)) 

我这样做是因为它只添加了一行代码。 谢谢你的所有答案。