我有一个已拨号(nums_dialed)的电话号码列表。 我也有一组电话号码,这是在客户的办公室(client_nums) 数量如何有效地找出有多少次我叫特定的客户端(总)Python中元素的数量设置
例如:
>>>nums_dialed=[1,2,2,3,3]
>>>client_nums=set([2,3])
>>>???
total=4
问题是我有一个large-ish数据集:len(client_nums)〜10^5;和len(num_dialed)〜10^3。
我有一个已拨号(nums_dialed)的电话号码列表。 我也有一组电话号码,这是在客户的办公室(client_nums) 数量如何有效地找出有多少次我叫特定的客户端(总)Python中元素的数量设置
例如:
>>>nums_dialed=[1,2,2,3,3]
>>>client_nums=set([2,3])
>>>???
total=4
问题是我有一个large-ish数据集:len(client_nums)〜10^5;和len(num_dialed)〜10^3。
哪位客户在他的办公室有10^5
号码?你是否为整个电话公司工作?
总之:
print sum(1 for num in nums_dialed if num in client_nums)
这会给你尽可能快的数量。
如果你想这样做了多个客户端,使用相同的nums_dialed
列表中,那么你可以先缓存上的每个数字的数据:
nums_dialed_dict = collections.defaultdict(int)
for num in nums_dialed:
nums_dialed_dict[num] += 1
然后就总结每个客户端上的:
sum(nums_dialed_dict[num] for num in this_client_nums)
这将比为每个客户端重复遍历整个数字列表快得多。
>>> client_nums = set([2, 3])
>>> nums_dialed = [1, 2, 2, 3, 3]
>>> count = 0
>>> for num in nums_dialed:
... if num in client_nums:
... count += 1
...
>>> count
4
>>>
即使对于您引用的大数字,应该也是相当有效的。
那是非常流行的方式来做到在单次排序列出的某种组合:
nums_dialed = [1, 2, 2, 3, 3]
client_nums = [2,3]
nums_dialed.sort()
client_nums.sort()
c = 0
i = iter(nums_dialed)
j = iter(client_nums)
try:
a = i.next()
b = j.next()
while True:
if a < b:
a = i.next()
continue
if a > b:
b = j.next()
continue
# a == b
c += 1
a = i.next() # next dialed
except StopIteration:
pass
print c
因为“集”是无序集合(不知道为什么它使用哈希值,而不是二进制树或排序列表),在那里使用它是不公平的。如果你喜欢列表或者通过更复杂的东西来生成有序的迭代器,你可以通过“平分”实现自己的“集合”。
在Python 2.7使用collections.Counter:
dialed_count = collections.Counter(nums_dialed)
count = sum(dialed_count[t] for t in client_nums)
或者干脆:LEN(过滤器(拉姆达X:X在client_nums,nums_dialed)) – ony 2010-03-27 07:44:58
@ony:这不是简单的。而且速度较慢并且使用更多的内存,因为它在计算'len'之前必须建立一个全新的列表。列表解析和生成器表达式比大多数情况下使用'filter'和'map'更好,特别是当您需要创建并调用一个新函数来使用它们时。 – nosklo 2010-03-27 07:55:11
@nosklo:对不起,我的错。 python2中的“filter”和“map”使用列表,但如果python3中的“len”将强制列表构建,那将会非常奇怪。 – ony 2010-03-27 08:14:30