反制工作不正常

时间:2018-05-20 14:16:40

标签: python python-3.x

以下代码查找文本文件以查看是否存在任何匹配项。例如,一行可以是"查理RY内容"下一行可能是"查理内容"。但是,计数器似乎已关闭,并且无法正确计数。

file = open("C:/file.txt", "rt")
data = file.readlines()
dictionary = dict()
counter = 0
count = 0
setlimit = 10 #int(input("Please enter limit for N. Then press enter:"))
parameter = ["RY", "TZ"]
for j in data:
    user = j.split()[0]
    identify = j.split()[1]
    for l in identify:
        #l = a[1:2]
        if user not in dictionary.keys() and identify not in parameter:
            count = 1
            data = dictionary.update({user:count})
            break
            #print(user, count,"<-- Qualifies")
        elif user in dictionary.keys() and identify not in parameter:
            data = dictionary.update({user: count})
            count += 1
            break
print(dictionary)

如代码中所示,它会查找RY或TZ并忽略此行,如果满足没有此条件的行,则计数器将增加1。

示例数据:

charlie TZ this is a sentence
zac this is a sentence
steve RY this is a sentence
bob this is a sentence
bob this is another sentence

预期产出:

{zac:1, bob:2}

3 个答案:

答案 0 :(得分:1)

如果你想增加点数,

count += 1

必须到来之前

dictionary.update({user: count})

换句话说,

elif user in dictionary.keys() and identify not in parameter:
    count += 1
    dictionary.update({user: count})
    break

请注意dictionary.update(...)修改dictionary并返回None。 由于它始终返回None,因此无需在data中保存该值。

或者,作为pointed out by Martijn Pieters,您可以使用

for j in data:
    ...
    if identify not in parameter:
        count += 1
        dictionary[user] = count

请注意,您不需要在两种不同情况下处理分配。 如果dictionary[user] = count不在user中,则作业dictionary会创建新的键/值对,并且即使它已分配,也会分配新值count。< / p>

请注意,只要条件为任何用户,单个count变量就会增加1。 如果您希望dictionary[user]为每个用户单独增加一个,请使用

for j in data:
    ...
    if identify not in parameter:
        dictionary[user] = dictionary.get(user, 0) + 1
如果dictionary.get(user, 0)位于dictionary[user],则

user会返回dictionary,否则会返回0.

另一种选择是使用collections.defaultdict

import collections
dictionary = collections.defaultdict(int)
for j in data:
    ...
    if identify not in parameter:
        dictionary[user] += 1

dictionary = collections.defaultdict(int), 每当dictionary[user]不在int()时,user都会被分配默认值dictionary。从那以后

In [56]: int()
Out[56]: 0
dictionary[user]不在user时,

dictionary会自动分配默认值0。

此外,user in dictionary是比user in dictionary.keys()更惯用的Python,尽管它们都返回相同的布尔值。事实上,你已经在使用这个成语 当你说identify not in parameter时。

虽然我们谈的是习语,但通常最好使用a with-statement来打开文件:

with open("data", "rt") as f:

因为这将保证在Python离开f语句时(通过到达语句内部代码的末尾,或者即使异常),文件句柄with也会自动关闭被提出。)

由于为identify分配了字符串值,例如'TZ',因此循环

for l in identify:

T,然后Z等值分配给变量l。 循环内部未使用l,并且没有明显的理由在identify中循环遍历字符。因此,您可能希望删除此循环。

对集合中成员资格的测试平均为a O(1) (constant speed) operation,而对列表中成员资格的测试为O(n)(时间通常会随着列表的大小而增加。)因此,最好使{ {1}}一套:

parameter

而不是两次调用parameter = set(["RY", "TZ"])

j.split

你只需要调用一次:

user = j.split()[0]
identify = j.split()[1]

请注意,这两个假设user, identify = j.split(maxsplit=2)[:2] 中至少有一个空格。 如果没有,原始代码段将引发j,而第二个引发IndexError: list index out of range

ValueError: need more than 1 value to unpack告诉maxsplit=2在(最多)完成两次拆分后停止拆分字符串。如果split是一个包含许多分割点的大字符串,这可以节省一些时间。

所以把它们放在一起,

j

答案 1 :(得分:0)

除了@unutbu所说的,您还需要重置count继续递增 其他用户

        if user not in dictionary.keys() and identify not in parameter:
            dictionary[user] = 1
            break
            #print(user, count,"<-- Qualifies")
        elif user in dictionary.keys() and identify not in parameter:
            dictionary[user] += 1
            break

如果没有这个改变,@ unutbu的答案仍然会有来自OP的不正确的计数逻辑。例如,对于此输入:

charlie TZ this is a sentence
zac this is a sentence
steve RY this is a sentence
bob this is a sentence
bob this is another sentence
zac this is a sentence
zac this is a sentence
bob this is a sentence

您的原始逻辑会给出结果:

{'bob': 4, 'zac': 3}

当两者都应该等于3时。

可能不需要{p> for l in identify:,实际上可能会干扰结果。

TO SUMMARIZE:您的代码可能如下所示:

file = open("C:/file.txt", "rt")
dictionary = dict()
setlimit = 10 #int(input("Please enter limit for N. Then press enter:"))
parameter = ["RY", "TZ"]                                                
for j in file:                                                          
    user, identify = j.split()[:2]
    if identity in parameter:     
        continue                  
    if user in dictionary.keys():
        dictionary[user] += 1         
    else:                              
        dictionary[user] = 1      
file.close()       
print(dictionary)    

答案 2 :(得分:0)

您已获得其他答案,涵盖您当前的方法。但是应该注意的是,python已经有一个collections.Counter对象做同样的事情 只是为了演示使用Counter(注意:这使用Py3进行*解包):

In []:
from collections import Counter
parameter = {"RY", "TZ"}
with open("C:/file.txt") as file:
    dictionary = Counter(u for u, i, *_ in map(str.split, file) if i not in parameter)

print(dictionary)

Out[]:
Counter({'bob': 2, 'zac': 1})