python - 计数器无法正常工作
问题描述
以下代码查找文本文件以查看是否有任何匹配项。例如,一行可能是“charlie RY content”,下一行可能是“charlie content”。但是,计数器似乎已关闭并且计数不正确。
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}
解决方案
如果你想增加计数,
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
.
或者,正如Martijn Pieters 所指出的,您可以使用
for j in data:
...
if identify not in parameter:
count += 1
dictionary[user] = count
请注意,您不需要在两种不同的情况下处理分配。如果不在 中,分配dictionary[user] = count
将创建新的键/值对,即使user
在dictionary
,它也会分配新值count
。
请注意,只要条件为 True对于任何用户count
,单个变量就会增加一。如果您想为每个用户独立增加一个,然后使用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
不在时自动分配默认值 0 dictionary
。
此外,虽然它们都返回相同的布尔值,但它user in dictionary
比 Python 更惯用。user in dictionary.keys()
事实上,当你说identify not in parameter
.
虽然我们讨论的是成语,但通常最好使用-statementwith
来打开文件:
with open("data", "rt") as f:
因为这将保证f
当 Python 离开with
-statement 时文件句柄会自动为您关闭(通过到达语句内代码的末尾,或者即使引发异常。)
由于identify
分配了字符串值,例如'TZ'
,循环
for l in identify:
T
将, then等值赋给Z
变量l
.
l
没有在循环内使用,也没有明显的理由循环identify
. 因此,您可能希望删除此循环。
测试集合中的成员资格平均是 O(1)(恒定速度)操作,而测试列表中的成员资格是 O(n)(时间通常随着列表的大小而增加。)所以最好做parameter
一套:
parameter = set(["RY", "TZ"])
而不是调用j.split
两次,
user = j.split()[0]
identify = j.split()[1]
你只需要调用一次:
user, identify = j.split(maxsplit=2)[:2]
请注意,这两个都假设j
. 如果没有,原始代码片段将 raise IndexError: list index out of range
,而第二个 raises ValueError: need more than 1 value to unpack
。
maxsplit=2
告诉split
在(最多)两个拆分完成后停止拆分字符串。如果j
是具有许多分割点的大字符串,这可以节省一些时间。
所以把这一切放在一起,
import collections
dictionary = collections.defaultdict(int)
setlimit = 10 #int(input("Please enter limit for N. Then press enter:"))
parameter = set(["RY", "TZ"])
with open("C:/file.txt", "rt") as f:
for line in f:
user, identify = line.split(maxsplit=2)[:2]
if identify not in parameter:
dictionary[user] += 1
dictionary = dict(dictionary)
print(dictionary)
推荐阅读
- javascript - 无法理解为什么类在不同的索引上被替换
- kubernetes - 为什么 calico 在 Kubernetes 中缺少一些节点对等地址?
- c# - 为什么我不能生成超过 6551 个随机数
- java - 如何测试返回复杂对象的函数?
- javascript - Firestore 对 Material UI 表的实时更新
- python - 如何减去两个数据框行
- python - ValueError:视图未返回 HttpResponse 对象。它返回 None 而不是
- python - 为什么 Python Web 应用程序抛出 *AttributeError: 'str' object has no attribute 'Div'*?
- coldfusion - 用于 Swagger OpenAPI 规范的 ColdFusion 客户端
- android - 无法获取“https://jcenter.bintray.com/com/android/tools/build/gradle/4.0.0/gradle-4.0.0.pom”