【问题标题】:Python optimization: Choosing between dictionary or list of list [closed]Python优化:在字典或列表列表之间进行选择[关闭]
【发布时间】:2017-09-20 21:02:00
【问题描述】:

我是 python3 的新手,我有一个关于解决这个问题的不同方法的问题。关于使用不同数据结构的问题。 我的问题是如何比较权衡与不同的采样技术

我在我的程序中使用了字典数据结构首先解决了这个问题。然后我尝试仅使用列表数据结构重写它。我试图考虑排序的好处,但我不知道这两种方法有什么区别。这两种方法似乎没有太大区别。

方法 1. 我使用字典在直方图中创建直方图键值对

方法 2 以字符串格式接收源文本并返回列表列表 其中每个子列表中的第一个元素是单词,第二个元素是 元素是它在源文本中的频率

# This program Analyze word frequency in a histogram
# sample words according to their observed frequencies
# takes in a source text in string format and returns a dictionary
# in which each key is a unique word and its value is that word's
# frequency in the source text
import sys
import re
import random
import time

def histogram(source_text):
    histogram = {}
    # removing any sort of string, removing any other special character
    for word in source_text.split():
        word = re.sub('[.,:;!-[]?', '', word)

        if word in histogram:
            histogram[word] += 1
        else:
            histogram[word] = 1
    return histogram

def random_word(histogram):
    probability = 0
    rand_index = random.randint(1, sum(histogram.values()))
    # Algorithm 1
    for (key, value) in histogram.items():
        for num in range(1, value + 1):
            if probability == rand_index:
                if key in outcome_gram:
                    outcome_gram[key] += 1
                else:
                    outcome_gram[key] = 1
                # return outcome_gram
                return key
            else:
                probability += 1

#    Method 2 takes in a source text in string format and returns a list #of lists
#    in which the first element in each sublist is the word and the #second element is its frequency in the source texts

  # Algorithm 2
    # for word in histogram:
    #     probability += histogram[word]
    #     if probability >= rand_index:
    #         if word in outcome_gram:
    #             outcome_gram[word] += 1
    #         else:
    #             outcome_gram[word] = 1
            # return word


if __name__ == "__main__":
    outcome_gram = {}
    dict = open('./fish.txt', 'r')
    text = dict.read()
    dict.close()

    hist_dict = histogram(text)
    for number in range(1, 100000):
        random_word(hist_dict)

【问题讨论】:

  • 早期优化是万恶之源......首先测量,然后切割,等等......我建议使用最易读的版本,可能是collections.Counter(my_text_corpus)
  • 感谢您的建议。我很欣赏这个建议。

标签: python python-3.x list dictionary


【解决方案1】:

哪个更易读?我认为字典版本更容易理解。另外,请注意,您可以将第二个方法中的 2 元组列表传递给 dict 构造函数,以重现第一个方法的输出。这应该让您了解这两种实现至少在某些方面是如何大致等效的。除非这会导致性能问题,否则我不会太担心。

Python 的优势在于,您可以用 5 行代码以可读的方式编写相同的代码。

import re, random
from collections import Counter

def histogram(text):
    clean_text = re.sub('[.,:;!-[]?', '', text)
    words = clean_text.split()
    return Counter(words)

def random_word(histogram):
    words, frequencies = zip(*histogram.items())
    return random.choices(words, frequencies, k=1)

【讨论】:

  • 更清晰......(虽然我只会对整个文本而不是单独运行每个单词)Counter(cleaner(text))
  • @joran IIRC, Counter 在整个字符串上将计算所有字母,而不是单词
  • Counter(cleaner(text).split()) 对不起,你是对的 :P ...但仍然不是清理每个单词,而是清理整个语料库一次
  • @JoranBeasley 说得好,已相应更新
【解决方案2】:

我一般同意 Joran Beasley 上面的评论,通常最好先解决你的问题,然后再回去重构以提高效率。

在使用直方图时,我建议在集合模块中查看Counter。集合模块作为一个整体真的很棒,并且有很多有用的容器。

另一个很酷的模块是Timeit 模块,它允许您在代码 sn-ps 上运行小型时序实验。请记住,执行速度取决于许多不一定在您的程序控制范围内的因素。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-15
    • 2015-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-21
    • 1970-01-01
    • 2023-04-09
    相关资源
    最近更新 更多