Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:更新频率表(以列表的形式)_Python - Fatal编程技术网

Python:更新频率表(以列表的形式)

Python:更新频率表(以列表的形式),python,Python,我有两个美国州缩写列表(例如): 我想要的结果是这个(基本上是一个有序的频率表): 我的想法是: s3=s1+s2 S=[[x,s3.count(x)] for x in set(s3)] 这工作得很好-不过,tbh,我不知道这是非常有效的内存 但是。。。有一个陷阱 s1+s2 …太大,无法保存在内存中,因此我要做的是将s1追加到长度为10K(是的,资源是有限的),然后对其进行汇总(使用上面的列表理解步骤),删除s1的内容,并用下一个数据块重新填充s1(上面仅表示为“s2”,用于演示)。。

我有两个美国州缩写列表(例如):

我想要的结果是这个(基本上是一个有序的频率表):

我的想法是:

s3=s1+s2
S=[[x,s3.count(x)] for x in set(s3)]
这工作得很好-不过,tbh,我不知道这是非常有效的内存

但是。。。有一个陷阱

s1+s2 
…太大,无法保存在内存中,因此我要做的是将s1追加到长度为10K(是的,资源是有限的),然后对其进行汇总(使用上面的列表理解步骤),删除s1的内容,并用下一个数据块重新填充s1(上面仅表示为“s2”,用于演示)。。。依此类推,直到循环到达数据的末尾

因此,对于循环的每次迭代,我想将列表的“基本”列表与当前迭代的列表相加。基本上,我的问题是,我如何添加这些: (当前主数据):

(新数据):

…获取(新的主数据):


…以某种合理有效的方式。如果这是更好地与字典或其他东西,我很好。不幸的是,我不能使用任何远程专用的Python模块——我所要做的就是在封闭、锁定、资源匮乏的Linux环境中使用最精简的Python 2.6版本(工作的危险)。非常感谢您的帮助

您可以使用
itertools.chain
高效地链接两个迭代器:

import itertools
import collections

counts = collections.Counter()

for val in itertools.chain(s1, s2): # memory efficient
    counts[val] += 1
一个
collections.Counter
对象是一个专门用于计数的
dict
。。。如果您知道如何使用
dict
,您可以使用
集合计数器。但是,它允许您更简洁地将上述内容写成:

counts = collections.Counter(itertools.chain(s1, s2))
另请注意,以下构造:

S=[[x,s3.count(x)] for x in set(s3)]
由于您正在循环中调用
s3.count
,因此时间效率也非常低。尽管如此,如果
len(set(s3))您可以随心所欲地运行多次,切割数据以适应内存/流式传输,这可能不会太糟糕

import collections

counter = collections.Counter()

counter.update(['foo', 'bar'])
assert counter['foo'] == counter['bar'] == 1

counter.update(['foo', 'bar', 'foo'])
assert counter['foo'] == 3
assert counter['bar'] == 2

assert sorted(counter.items(), key=lambda rec: -rec[1]) == [('foo', 3), ('bar', 2)]
最后一行使用否定计数作为排序键,使较高的计数排在第一位


如果您的计数结构不适合内存,那么您需要一个(基于磁盘的)数据库,如Postgres,或者可能只是一台具有更多内存和更高效键值存储的机器,如Redis。

循环是否违背了
计数器的目的
counts=collections.Counter(itertools.chain(s1,s2))
应该更好。@schwobaseggl是的,最初我使用的是
OrderedDict
,因为我认为顺序可能很重要,然后在重新阅读op时改为
Counter
,它说“dict很好”。我不确定它是否“违背了目的”,但它肯定不是那么简单。@juanpa.arrivillaga非常感谢-这非常有效!实际上,我在循环中完成了这项工作,就像在第一个示例中一样,因为我需要一直附加到Counter()对象(每次len(s)达到10K)。而且-实际上我确实需要对结果进行排序-所以在循环之后,我只是使用:freqs=sorted(counts.items())转换为一个排序列表(tuple?)--感谢你们两位!谢谢@9000——我也将使用这个解决方案——始终可以使用字典进行更多练习。。。。
S=[['CA',2],['CO',1],['FL',1],['GA',1],['IN',1],['MA',4],['OH',4]]
import itertools
import collections

counts = collections.Counter()

for val in itertools.chain(s1, s2): # memory efficient
    counts[val] += 1
counts = collections.Counter(itertools.chain(s1, s2))
S=[[x,s3.count(x)] for x in set(s3)]
it1 = iter(s1)
it2 = iter(s2)

for val in it1:
    ...

for val in it2:
    ...
import collections

counter = collections.Counter()

counter.update(['foo', 'bar'])
assert counter['foo'] == counter['bar'] == 1

counter.update(['foo', 'bar', 'foo'])
assert counter['foo'] == 3
assert counter['bar'] == 2

assert sorted(counter.items(), key=lambda rec: -rec[1]) == [('foo', 3), ('bar', 2)]