2

作为我项目的一部分,对于字典 d 中的每个单词(如下面的示例代码片段所示),我需要检查它是否存在于不同的列表中f1, f2, f3。我在这里只展示了 3 个列表。根据发生情况,我需要计算两个输出值(规则输入和权重)。我在这里面临的问题是,这个词可以出现在任意数量的列表中,比如 dict d 中的 word1 出现在列表中f1, f2, f3(如下所示)和 dict d 中的 word2 出现在 f1 和 f2 中,而 word3 仅出现在一个列表 f3 中。我有 100 个这些单独的列表。我需要一种有效且直接的方法来计算字典 d 中每个单词的输出值(规则输入和权重),基于它们在这些列表中的不同出现,这样我就不必检查每个出现的组合并写一个单独的条件,这会使事情变得复杂和丑陋。

PS:列表大小不同。在下面的示例中,f1、f2 和 f3 具有不同的大小。

我的代码:

import itertools

d = {'Rosa': 0.023, 'code': 0.356, 'Syntel': 0.144, 'Robotics': 0.245, 'Web': .134, 'sanskrit': 0.23, 'Tamil': 0.23}
f1 = [['Syntel', 0.2, 4, 0.46, 7, 0.9], ['code', 0.45, 9, 0.43, 2, 0.23], ['Robotics', .43, 3, .1, 3, .73]]
f2 = [['Web', 0.5, 5, 0.06, 6, 0.9], ['code', 0.05, 1, 0.28, 2, 0.73]]
f3 = [['Web', 0.5, 5, 0.06, 6, 0.9], ['sanskrit', 0.05, 1, 0.28, 2, 0.73], ['Tamil', 0.23, 4, .13, 5, .23], ['code', 0.32, 4, 0.12, 4, .24]]

# specific case where I am checking if a word of the dictionary occurs in all of the lists f1, f2 and f3
# I have to write chunk of code for every possible combo of occurrence which I think is a bad approach
# I am brain stuck ! Help please !!
for word, score in d.iteritems():
    for x in f1:
        if word == x[0]:
            for y in f2:
                if word == y[0]:
                    for z in f3:
                        if word == z[0]:
                            A = x[2] * x[3]
                            B = x[4] * x[5]
                            C = y[2] * y[3] + 1
                            D = y[4] * y[5] + 1
                            E = z[2] * z[3] + 1
                            F = z[4] * z[5] + 1
                            mfs = [[A, B], [C, D], [E, F]]
                            weights = sum([x[3], x[5], y[3], y[5], z[3], z[5]])
                            rule_inputs = list(itertools.product(*mfs))
                            len_comb = len(rule_inputs)
                            # 6 --> need code to find this automatically
                            weight_factor = (len(mfs) * len_comb) / 6
                            weights *= weight_factor
                            rule_inputs = sum([sum(r) for r in rule_inputs])
                            print word, rule_inputs, weights
4

2 回答 2

4

正如 Joel Cornett 所说,您可能应该首先使用dicts 而不是lists。

但是如果你list出于某种原因需要 s ......好吧,如果你要搜索list多次,你可能想要构建一个dict来搜索:

d1 = {elem[0]: elem for elem in f1}

然后,而不是这个:

for z in f3:
    if word == z[0]:

......你可以这样做:

z = d3.get(word)
if z is not None:

您可能还想关注 EAFTP 和try整个事情。你的整个循环看起来像这样:

for word, score in d.iteritems():
    try:
        x, y, z = d1[word], d2[word], d3[word]
    except KeyError:
        continue
    A = x[2] * x[3]
    # etc.

这是假设您特别需要三个列表,而不是任意数字。如果您需要能够处理任意数量的列表,您可以这样做:

list_of_dicts = [{elem[0]: elem for elem in lst} for lst in list_of_lists]
for word, score in d.iteritems():
    try:
        values = [d[word] for d in list_of_dicts]
    except KeyError:
        continue
    A = values[0][2] * values[0][3]
    # etc.

有几种替代方法,但这可能是您想要的。

您可以sort列出并使用每个列表,bisect而不是迭代线性搜索,或者使用类似的东西SortedCollection为您或blist.sortedlist类似类型包装。这使得搜索 O(log N) 而不是 O(N),并使代码更简单。但是 adict使搜索 O(1) 而不是 O(N),并使代码与使用排序列表一样简单,因此,除非您正在处理不可散列的键(而您不是),何必?

您还可以通过编写一个函数来包装for/ ,这为您提供与or相同的简单性,但没有性能提升。如果键既不可散列也不可排序,或者如果您有大量的小列表(如此之小以至于线性搜索实际上比 dict 或树查找更快——可能大小约为 2-3?),这可能很有用。但除此之外,你只是在做额外的工作(编写包装器)来减慢自己的速度,所以再说一次,为什么要麻烦呢?iffind_in_listdictsortedlistfind_in_list

于 2013-04-11T20:30:55.960 回答
0

看看 mapreduce 库
https://developers.google.com/appengine/docs/python/dataprocessing/overview

于 2013-04-11T20:21:59.237 回答