[英]List the second item in a tuple (used as a Python dictionary key) grouped by the first item
I have a dict of tuples: (port , freq). 我有一个元组字典:(port,freq)。
d = {(0, 410): None, (1, 640): None, (2, 88): None, (2, 410): None, (0, 33): None}
I want to collect all tuples with the same port number, the frequencies for these are unique. 我要收集具有相同端口号的所有元组,这些元组的频率是唯一的。 I then want to list these frequencies. 然后,我想列出这些频率。
If I can do this without having a value that would be great as it isn't needed, however port, freq must be unique and making them keys allowed me to achieve this. 如果我可以在没有一个不需要的值的情况下做到这一点,那么port的freq必须是唯一的,并且使它们成为我可以实现的键。
I managed to list all the frequencies but this is not what I want. 我设法列出了所有频率,但这不是我想要的。
_, freq = zip (*list( d.keys() ))
Can someone show me an efficient pythonic way to do this please? 有人可以告诉我一种有效的pythonic方法吗?
zip
ing is not an inefficient way of doing what you need. zip
不是完成您所需的低效方法。
A simple list comprehension would be sufficient: 一个简单的列表理解就足够了:
freq = [x[1] for x in d]
Or: 要么:
import operator as op
freq = list(map(op.itemgetter(1), d))
the None
valued dictionary seems awkward, a set works too None
值字典看起来很尴尬,一套也可以
d = {(0, 410), (1, 640), (2, 88), (2, 410), (0, 33)}
type(d)
Out[410]: set
itertools groupby is the tool if standard libs are allowed 如果允许标准库,则itertools groupby是该工具
from itertools import groupby
grouped = [(k, *g) for k, g in groupby(sorted(list(d),
key=lambda x: x[0]),
key=lambda x: x[0])]
print(*grouped, sep='\n')
(0, (0, 410), (0, 33))
(1, (1, 640))
(2, (2, 88), (2, 410))
what I came up with for pulling apart the groupby structure seems ugly 我想出的分解groupby结构的方法看起来很丑
[(b[0], list(b[-1]))
for b in [(a[0], *zip(*a[1:]))
for a in grouped ]]
Out[399]: [(0, [410, 33]), (1, [640]), (2, [88, 410])]
This is exactly the kind of problem collections.defaultdict
was created for. 这正是创建问题collections.defaultdict
的类型。
This is how you would create a defaultdict
that creates a new list
when a missing key is accessed: 这是您将创建一个defaultdict
,当访问缺少的键时将创建一个新list
:
from collections import defaultdict as ddict
dd = ddict(list)
Now you can just populate your default dictionary with the second item from all your tuples: 现在,您可以使用所有元组中的第二项填充默认词典:
for port, freq in d:
dd[port].append(freq)
Done. 做完了 This works because each time a missing key with the value of port
is accessed, a new list
is created, and then you just append to that list. 之所以可行,是因为每次访问缺少port
值的键时,都会创建一个新list
,然后将其追加到该列表中。 If the key is already there, you just append to the existing list. 如果密钥已经存在,则只需追加到现有列表即可。
Now you can access all the frequencies for any given port: 现在,您可以访问任何给定端口的所有频率:
print(dd[0])
Note: if your goal for your first data structure is to have a collection of unique tuples, instead of using a dictionary to hold your tuples I suggest using a set
instead. 注意:如果您的第一个数据结构的目标是拥有唯一元组的集合,而不是使用字典来保存元组,那么我建议使用set
。 A set
is just that- a set of unique items, with no associated values to consider: 一set
只是-一组唯一的项目,没有要考虑的关联值:
>>> s = {(0, 410), (1, 640), (2, 88), (2, 410), (0, 33)}
>>> type(s).__name__
'set'
A simple solution. 一个简单的解决方案。
Let's make a dictionary where each key is the port and each value is a list of the frequencies, this allows you to sum them or operate on them as you like and gives you O(1) access to them! 让我们做一个字典,其中每个键是端口,每个值是频率列表,这使您可以对它们进行求和或对其进行操作,并允许O(1)访问它们!
#first let's make a dict of all the keys with empty lists
my_dict = dict.fromkeys( [str(x[0]) for x in d.keys()], [])
#now let's append those frequencies!
[my_dict[str(soc)].append(freq) for soc, freq in d.keys()]
note that this doesnt give you a sorted structure, but you can save a sockets list and use it for the from_keys method and have a sorted way of accessing sockets. 请注意,这没有给您排序的结构,但是您可以保存套接字列表并将其用于from_keys方法,并具有访问套接字的排序方式。 eg 例如
sockets = [str(x[0]) for x in d.keys()] #str() allows us to use an integer as a key, keep this in mind!
This however, makes it really easy to access all the different frequencies for a given socket, just like this: 但是,这使得访问给定套接字的所有不同频率变得非常容易,如下所示:
my_dict['socket']
Interpreter copy paste demo: 解释器复制粘贴演示:
>>> d = {(0, 410): None, (1, 640): None, (2, 88): None, (2, 410): None, (0, 33): None}
>>> my_dict = dict.fromkeys( [str(x[0]) for x in d.keys()], [])
>>> [my_dict[str(soc)].append(freq) for soc, freq in d.keys()]
[None, None, None, None, None]
>>> my_dict
{'0': [410, 640, 88, 410, 33], '1': [410, 640, 88, 410, 33], '2': [410, 640, 88, 410, 33]}
>>>
Note that this converts form the current format that you have (or edit your post and ping me :D). 请注意,这会转换为您当前使用的格式(或编辑您的帖子并ping me:D)。 You can adapt whatever code you may have to get similar results and have equivalent level of happiness to access things. 您可以调整可能需要的任何代码,以获取相似的结果,并获得与事物相同的幸福感。 Keeping a sorted list of the keys makes life really easy. 保留按键的排序列表使生活变得非常轻松。 Python3 is supposed to keep dictionaries sorted by default now so don't take my word on it but if you use my_dict.keys() it should return them in a sorted way but I could be wrong about how that operates. Python3应该默认保留字典的默认排序,所以不要相信我,但是如果您使用my_dict.keys(),它应该以排序的方式返回它们,但是我可能会错了。
A dict of socket-> frequencies will be the easiest to deal with. 套接字->频率的决定将是最容易处理的。 An optional sorted list of sockets might help also 可选的套接字排序列表可能也有帮助
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.