根据第一个元素

时间:2016-05-04 21:55:36

标签: python list dictionary tuples n-gram

我正在尝试创建一个列表,其中包含第一个元素的词典中最常见的元组。例如: 如果d是我的字典:

d = {(Hello, my): 1,(Hello, world):2, (my, name):3, (my,house):1} 

我想获得一个这样的列表:

L= [(Hello, world),(my, name)]

所以我试试这个:

L = [k for k,val in d.iteritems() if val == max(d.values())]

但这只给了我所有元组的最大值:

L = [('my', 'name')]

我在想,也许我必须通过我的字典并为每个元组的每个第一个字创建一个新的字典,然后找到最频繁的并将其放在列表中,但我很难将其转换为代码。

4 个答案:

答案 0 :(得分:3)

from itertools import groupby

# your input data
d = {('Hello', 'my'): 1,('Hello', 'world'):2, ('my', 'name'):3, ('my','house'):1}

key_fu = lambda x: x[0][0]  # first element of first element,
                            # i.e. of ((a,b), c), return a

groups = groupby(sorted(d.iteritems(), key=key_fu), key_fu)
l = [max(g, key=lambda x:x[1])[0] for _, g in groups]

答案 1 :(得分:2)

如果只是重新键入第一个单词的映射,这在O(n)中是可以实现的:

>>> d = {('Hello','my'): 1, ('Hello','world'): 2, ('my','name'): 3, ('my','house'): 1}
>>> d_max = {}
>>> for (first, second), count in d.items():
...     if count >= d_max.get(first, (None, 0))[1]:
...         d_max[first] = (second, count)
...         
>>> d_max
{'Hello': ('world', 2), 'my': ('name', 3)}
>>> output = [(first, second) for (first, (second, count)) in d_max.items()]
>>> output
[('my', 'name'), ('Hello', 'world')]

答案 2 :(得分:0)

在我看来,你不应该只获得所有d值的最大值,否则它只会获得你的字典中包含的最大值,在指定的情况下为3。 我要做的是创建一个中间列表(也许这可以隐藏),它将键的第一部分保留在内存中作为第二个元素,并将计数器作为第一个元素。通过这种方式,您可以获得排序列表中的第一个元素,以获得真正的最大密钥。

答案 3 :(得分:0)

您拥有成对的单词和与其相关联的计数。您可以将信息存储(或转换为)3元组:

d = [
  ('Hello', 'my', 1),
  ('Hello', 'world', 2), 
  ('my', 'name', 3),
  ('my', 'house', 1)
]

对于第一个位置的每个单词,您希望找到最常出现在第二个位置的单词。根据第一个单词(任何顺序,只是将它们分组),然后根据计数(降序)对数据进行排序。

d.sort(lambda t1,t2: cmp(t2[2],t1[2]) if (t1[0]==t2[0]) else cmp(t1[0],t2[0]))

最后,迭代生成的数组,跟踪遇到的最后一个单词,并仅在遇到第一个位置的新单词时追加。

L = []
last_word = ""
for word1, word2, count in d:
   if word1 != last_word:
     L.append((word1,word2))
     last_word = word1

print L

通过运行此代码,您获得[('Hello', 'world'), ('my', 'name')]