Python文件i / o

时间:2014-05-04 00:45:52

标签: python regex file-io

我编写了这段代码,应该解析输入文件中的行 输入格式: 电影ID可以是多个条目,因此我们应该计算平均值 输出: **没有重复(这是问题)

import re
f = open("ratings2.txt", "rb")
fo = open("ratings3.txt", "wb")
lines = f.readlines()
movielist=[]
for line in lines:
    m_obj = re.search(r"<(\S+), (\S+)>", line)
    x= m_obj.group(1)
    ratinglist=[]
    if x not in movielist:
        movielist.append(x)
        for subline in lines:
            n_obj = re.search(r"<(\S+), (\S+)>", subline)
            if n_obj.group(1)==x:
                ratinglist.append(float(n_obj.group(2)))
                av= (float(sum(ratinglist))/float(len(ratinglist)))
                final= "<%s, %f>\n" %(n_obj.group(1), av)                
                fo.write(final)
f.close()
fo.close()

输入文件:

<122, 5>
<185, 5>
<122,4.5>

期望的输出:

<122, 4.75>
<185, 5>

但是这里的问题似乎是代码双循环每个实例并添加一行实例第一个条目......任何人都可以帮忙吗?

实际输出:

<122, 5>
<122, 4.75>
<185, 5>

4 个答案:

答案 0 :(得分:2)

该行&#34;如果x不在movielist&#34;对于第一行和第二行都是如此。 对于第一行,当您读取第二个循环中的所有行时,&#34;如果n_obj.group(1)== x&#34;对于第一行和第三行(如果122 == 122)将为真。所以&#34; fo.write(final)&#34;将被执行两次。在程序的整个过程中,&#34; fo.write(final)&#34;将执行三次,因此您将获得三行输出。

至少可以解释为什么你得到三行而不是预期的两行。

答案 1 :(得分:1)

以下代码将执行您想要的操作:

import re
a = {}
with open('input.txt', 'rb') as f:
    for line in f:
        x = re.search(r'<([^,]+),\s?([^>]+)>', line)
        x,y = float(x.group(1)), float(x.group(2))
        if x in a:
            a[x].append(y)
        else:
            a[x] = [y]

for key in a:
    a[key] = sum(a[key])/len(a[key])

print a

with open('output.txt', 'wb') as f:
    for i,j in a.items():
        f.write('<'+str(i)+', '+str(j)+'>\n')

[input.txt]
<122, 5>
<185, 5>
<122,4.5>

[output.txt]
<122, 4.75>
<185, 5>

答案 2 :(得分:1)

感谢Mark Lutton 我使用以下条件编辑了“subline”循环

for subline in lines:
        n_obj = re.search(r"<(\S+), (\S+)>", subline)
        if subline == ln:
            ratinglist.append(float(n_obj.group(2)))
        elif n_obj.group(1)==x:
            ratinglist.append(float(n_obj.group(2)))
            av= (float(sum(ratinglist))/float(len(ratinglist)))
            final= "<%s, %.2f>\n" %(n_obj.group(1), av)                
            fo.write(final)

答案 3 :(得分:0)

您的代码是缩进的,以便'if n_obj.group(1)== x:'并且对行中的每一行执行相关的写入'fo',以便输出文件中的记录对应于每个输入记录不是它应该做的。

应更改“if”块,以便“平均值写在循环外”,但检查movie_id是否仍在循环内。 目前,您正在为行中的每个子行写平均值。

只需相应地更改代码和缩进即可。