Sch*_*tti 10 python dictionary set
这是我的第一个python程序 -
要求:在每行中读取由{adId UserId}组成的文件.对于每个adId,打印唯一userIds的数量.
这是我的代码,从阅读python文档放在一起.你能不能给我反馈一下如何以更多的python-ish方式写这个?
代码:
import csv
adDict = {}
reader = csv.reader(open("some.csv"), delimiter=' ')
for row in reader:
adId = row[0]
userId = row[1]
if ( adId in adDict ):
adDict[adId].add(userId)
else:
adDict[adId] = set(userId)
for key, value in adDict.items():
print (key, ',' , len(value))
Run Code Online (Sandbox Code Playgroud)
谢谢.
unu*_*tbu 18
恭喜,您的代码非常好.您可以使用一些小技巧来缩短/简化它.
有一个名为defaultdict的漂亮对象类型,由collections模块提供.您无需检查adDict是否具有adId键,而是可以设置一个默认的dict,其作用类似于常规字典,除非它在没有键时自动为您提供空集().所以你可以改变
if ( adId in adDict ):
adDict[adId].add(userId)
else:
adDict[adId] = set(userId)
Run Code Online (Sandbox Code Playgroud)
简单地说
adDict[adId].add(userId)
Run Code Online (Sandbox Code Playgroud)
而且,而不是
for row in reader:
adId = row[0]
userId = row[1]
Run Code Online (Sandbox Code Playgroud)
你可以缩短它
for adId,userId in reader:
Run Code Online (Sandbox Code Playgroud)
编辑:正如帕克在评论中指出的那样,
for key, value in adDict.iteritems():
Run Code Online (Sandbox Code Playgroud)
如果要在循环中同时使用键和值,则迭代dict是最有效的方法.在Python3中,您可以使用
for key, value in adDict.items():
Run Code Online (Sandbox Code Playgroud)
因为items()返回一个迭代器.
#!/usr/bin/env python
import csv
from collections import defaultdict
adDict = defaultdict(set)
reader = csv.reader(open("some.csv"), delimiter=' ')
for adId,userId in reader:
adDict[adId].add(userId)
for key,value in adDict.iteritems():
print (key, ',' , len(value))
Run Code Online (Sandbox Code Playgroud)
Ale*_*lli 10
代码行:
adDict[adId] = set(userId)
Run Code Online (Sandbox Code Playgroud)
不可能做你想要什么-它将把字符串userId为字母顺序,因此,例如,如果userId是aleax你会得到一组四个选项,就像,比如说,set(['a', 'l', 'e', 'x']).稍后,.add(userId)when userId将aleax再次添加第五个项,即字符串'aleax',因为.add(与set initializer不同,它采用iterable作为其参数)将单个项作为其参数.
要使用单个项目创建集合,请set([userId])改为使用.
这是一个相当频繁的bug,所以我想清楚地解释它.话虽如此,defaultdict正如其他答案中所建议的那样,显然是正确的方法(避免setdefault,这从来就不是一个好的设计,既没有良好的表现,也不是很模糊).
我也会避免csv在每一行上使用.split和.strip的简单循环有点过分了...
您可以将for循环缩短为:
for row in reader:
adDict.setdefault(row[0], set()).add(row[1])
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
643 次 |
| 最近记录: |