我正在计算一个说,整数的列表。我有一个csv文件中的数字列表,我能够读入,看起来像4,245,34,99,340,... 我正在做的是尝试返回一个带有键:值对的字典,其中键是来自csv文件的整数值,值是它在列表中出现的次数。我不确定我在这里做错了什么,任何帮助都将不胜感激
allCounts = dict()
rows = csv.reader(open('...csv'), delimiter=',')
for intValue in rows:
intVal = intValue[0]
for intVal, numAppearances in allCounts:
if intVal in allCounts:
allCounts[numAppearances] = allCounts[numAppearances]+1
else:
allCounts[numAppearances] = 1
答案 0 :(得分:8)
听起来像你想要的是一个Counter对象:
http://docs.python.org/library/collections.html#counter-objects
另外我认为您可能想要使用CSV模块:
http://docs.python.org/library/csv.html
使用内置模块应该更容易:)
要获得类似这样的行应该有效:
csvfile = open("example.csv")
dialect = csv.Sniffer().sniff(csvfile.read(1024))
csvfile.seek(0)
reader = csv.reader(csvfile, dialect)
然后你应该能够做到这一点:
c = Counter(reader)
答案 1 :(得分:5)
你正在做的是遍历每个单元格的整个字典,这有点奇怪,可能不是你想要做的。你真正想要做的只是查看字典并增加有问题的密钥。所以:
# first part stays mostly the same
rows = csv.reader(open("...csv") )
allCounts = {}
for row in rows:
for field in row:
allCounts[field] = allCounts.get(field, 0) + 1
最后一行使用dict
的一个不错的小功能,如果找不到该键,则会返回默认值。
在您自己的代码中,有一些值得注意的缺陷。最重要的是第四和第五行。从所选行中提取第一个字段并将其分配给intVal
,然后在迭代dict时将其用作键,从而完全屏蔽intVal
。这意味着任务完全不起作用。
if
子句注定要失败。您正在检查密钥是否在dict中,但是您通过迭代来自同一个dict的密钥来提出该密钥。当然,关键在于词典。
下一个问题是您的else
子句正在修改您正在迭代的集合。 Python不保证这对于dicts是如何工作的,所以不要这样做
就此而言,没有任何理由可以在dict上进行迭代。您可以直接获取您感兴趣的任何键值对。您应该迭代的是文件中的整数列表。
CSV文件始终构造为形成行的值列表(通常用逗号分隔),行由换行符分隔。 CSV模块通过返回列表列表来保留此视图。要深入查看实际值,您需要遍历每一行,然后遍历该行中的每个字段。您的代码遍历每一行,然后遍历每行的dict中的每个键,忽略字段。
答案 2 :(得分:0)
摆脱intVal = intValue[0]
由于intValue是一个字符串,因此您将成为该数字的字符串表示形式中的第一个字符。你真正想要的是intValue = int(intValue)
。
然后你的逻辑都错了 - 目前allCounts被初始化为一个空字典,你不能迭代。你想要做的是迭代你已经存在的csv.reader
返回的值。从那里你的逻辑很接近 - 不幸的是,这既不是马蹄铁也不是手榴弹。你想要的是这个:
# Checks to see if intValue is a key in the dictionary
if intValue in allCounts:
# If it is then we want to increment the current value
# += 1 is the idiomatic way to do this
allCounts[intValue] += 1
else:
# If it is not a key, then make it a key with a value of 1
allCounts[intValue] = 1