生成器表达式正在丢弃大量元组对,例如以列表形式:
pairs = [(3, 47), (6, 47), (9, 47), (6, 27), (11, 27), (23, 27), (41, 27), (4, 67), (9, 67), (11, 67), (33, 67)]
对于成对的每一对,key=pair[0]和value=pair[1],我想将这些成对的数据流输入字典,以累积地添加各个键的值。显而易见的解决方案是:
dict_k_v = {}
for pair in pairs:
try:
dict_k_v[pair[0]] += pair[1]
except:
dict_k_v[pair[0]] = pair[1]
>>> dict_k_v
{33: 67, 3: 47, 4: 67, 6: 74, 9: 114, 11: 94, 41: 27, 23: 27}
但是,这可以通过生成器表达式或不使用for循环的类似构造来实现吗?
编辑
为了澄清这一点,生成器表达式抛出了大量元组对:
(3,47),(6,47),(9,47),(6,27),(11,27),(23,27),(41,27),(4,67),(9,67),(11,67),(33,67)。。。
我想在生成每一对键值时,将每一对键值累积到一个字典中(参见Paul McGuire的答案)。pairs=list[]语句是不必要的,对此表示抱歉。对于每对(x,y),x是一个整数,y可以是一个整数或小数/浮点数。
我的生成器表达式的形式是:
((x,y) for y in something() for x in somethingelse())
并希望将每个(x,y)对累加为一个defaultdict。哦。
为了便于讨论,这里有一个简单的生成器函数来提供一些数据:
下面是一个基本的解决方案,它使用Python for循环来使用生成器并统计每个键值对的计数
将打印如下内容:
但我们可以创建一个协程,它将接受发送给它的每个键值对,并将它们全部累加到传递给它的defaultdict中:
我们将使用tally defaultdict初始化协程,并通过向它发送一个None值来准备接受值:
我们可以使用for循环或列表理解将所有生成器值发送到协同程序:
或者
但是,我们将使用大小为零的deque来处理生成器表达式的所有值,而不创建不必要的None临时列表:
现在我们再来看看这些价值观:
我们得到了另一个与第一个类似的列表:
在David Beazley的页面上阅读更多关于协作的信息:http://www.dabeaz.com/coroutines/
您可以使用元组解构和^{} 来大大缩短循环:
这仍然使用for循环,但您不必处理以前从未见过密钥的情况。我认为这可能是最好的解决方案,无论是可读性方面还是性能方面。
使用
证明概念groupby
也就是说,你可以用^{} 来做,但这有点麻烦:
而且,这实际上应该比第一种方法性能更低,因为需要为排序创建所有对的内存中列表。
相关问题 更多 >
编程相关推荐