我正在尝试编写一个包含频率和整数字典的程序,并返回一个包含所有出现超过min_times的单词的元组列表。
def words_often(freqs, min_times):
tuple_list = []
for key in freqs:
word_list = []
if freqs[key] > min_times:
store_value = freqs[key]
for key2 in freqs:
if freqs[key2] == store_value:
word_list += [key2]
if freqs[key] not in tuple_list:
tuple_list += [(word_list, store_value)]
return tuple_list
#test program
freqs = {'yeah':15, 'one': 1, 'crazy': 3, 'lonely': 1}
print(words_often(freqs, 0))
然而,有一些错误,上面测试的返回值是:
[([‘yeah’], 15), ([‘one’, ‘lonely’], 1), ([‘crazy’], 3), ([‘one’, ‘lonely’], 1)]
此返回值不应该包含最后一个条目,因为它是重复的。
如何使我的代码更简单,因为很多事情正在发生,我无法确定问题。
编辑:我需要将元组内的单词分组到列表中。例如,第一个条目应该是(['yeah'],15),对于具有相同值(一个和孤独)的单词,我需要将它们分组为(['one','lonely'],1)
答案 0 :(得分:1)
由于您希望按值对键进行分组,因此可以使用itertools.groupby
:
from itertools import groupby
data = {'yeah':15, 'one': 4, 'crazy': 3, 'lonely': 4}
min_times = 3
get_value = lambda kv: kv[1]
sorted_data = sorted(data.items(), key= get_value, reverse=True)
print(sorted_data)
# [('yeah', 15), ('one', 4), ('lonely', 4), ('crazy', 3)]
print([([v[0] for v in vs], k) for k,vs in groupby(sorted_data, key= get_value) if k > min_times])
# [(['yeah'], 15), (['one', 'lonely'], 4)]
答案 1 :(得分:0)
使用collections.defaultdict
freqs = {'yeah':15, 'one': 1, 'crazy': 3, 'lonely': 1}
from collections import defaultdict
def words_often(freqs, min_times):
d_dict = defaultdict(list)
for k,v in freqs.items():
d_dict[v].append(k)
return [(v,k) for k,v in d_dict.items() if k>min_times]
print(words_often(freqs, 0))
输出:
[(['yeah'], 15), (['one', 'lonely'], 1), (['crazy'], 3)]
答案 2 :(得分:0)
List comprehension可能会使您的代码更简单。
from collections import defaultdict
def words_often(freqs, min_times):
words = [(key, freqs[key]) for key in freqs if freqs[key] >= min_times]
# words = [('yeah', 15), ('one', 1), ('crazy', 3), ('lonely', 1)]
d = defaultdict(list)
for word, freq in words:
d[freq].append(word)
# d = {15: ['yeah'], 1: ['one', 'lonely'], 3: ['crazy']}
return [(d[freq], freq) for freq in d]
# Test
freqs = {'yeah':15, 'one': 1, 'crazy': 3, 'lonely': 1, 'zero':0}
print(words_often(freqs, 1))
# [(['yeah'], 15), (['one', 'lonely'], 1), (['crazy'], 3)]
答案 3 :(得分:0)
freqs = {'yeah':15, 'one': 1, 'crazy': 3, 'lonely': 1}
m = 0
from collections import defaultdict
def answer(d, m):
out = defaultdict(list)
for e, i in d.items():
if i > m:
out[i].append(e)
return [(e, i) for i, e in out.items()]
这样可行。
答案 4 :(得分:0)
如果给定list
中的值大于给定的最低要求,则会从给定tuples
返回dict
dict
:
def convert(items, min):
return [(key, items[key]) for key in items.iterkeys() if items[key] > min]
例如,显示dict
:
freqs = {'yeah': 15, 'one': 1, 'crazy': 3, 'lonely': 1}
convert(freqs, 0)
# [('crazy', 3), ('lonely', 1), ('yeah', 15), ('one', 1)]
这基本上在一行上for loop
执行,称为list comprehension
。了解它们,它们将拯救你的生命。
如果您希望tuple
中的第一个值为list
,最简单的方法是在值的插入周围添加[]
:
def convert(items, min):
return [([key], items[key]) for key in items.iterkeys() if items[key] > min]
另一个给定dict
的例子:
freqs = {'yeah': 15, 'one': 1, 'crazy': 3, 'lonely': 1}
convert(freqs, 0)
# [(['crazy'], 3), (['lonely'], 1), (['yeah'], 15), (['one'], 1)]
答案 5 :(得分:0)
您可以使用Pandas:
import pandas as pd
[(word, freq) for freq, word in (
pd.Series(freqs)
.reset_index()
.groupby(0, as_index=False)
.agg(lambda x: list(x))
.values
)]
# [(['lonely', 'one'], 1), (['crazy'], 3), (['yeah'], 15)]
无论您最终采用何种解决方案,考虑这是对字频进行reduce
操作可能会有所帮助,并且频率占用word:freq
键:值对中的值槽。
reduce
和/或groupby
操作通过折叠键,然后创建关联的值的某些聚合来工作。这就是为什么你会看到许多这些答案在某个时候反转freqs
,以便为reduce
操作提供一些信息。