用于构建元组列表的程序

时间:2017-10-22 15:29:38

标签: python python-3.x debugging

我正在尝试编写一个包含频率和整数字典的程序,并返回一个包含所有出现超过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)

6 个答案:

答案 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操作提供一些信息。