以下代码查找文本文件以查看是否存在任何匹配项。例如,一行可以是"查理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}
答案 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})