使用字典的“get”方法选择大小写。为什么它总是选错东西?

2024-10-02 22:35:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用dictionary的get()方法根据变量键值选择大小写。问题是,它总是为键选择错误的大小写。我不确定我是否使用了正确的词语来解释它,但是代码应该足够清楚。在

di_eqns = {"PSME": Pred_PSME(liLn), "ABAM":Pred_ABAM(liLn), \
           "ABCO":Pred_Abies(liLn), "ABGR":Pred_Abies(liLn), \
           "ABLA":Pred_Abies(liLn), "ABMA":Pred_Abies(liLn), \
           "ABSH":Pred_Abies(liLn), "ABPR":Pred_ABPR(liLn), \
           "CADE27":Pred_Cedar(liLn), "CHLA":Pred_Cedar(liLn), \
           "CHNO":Pred_Cedar(liLn), "THPL":Pred_Cedar(liLn), \
           "LALY":Pred_LALY(liLn), "LAOC":Pred_LAOC(liLn), \
           "PIEN":Pred_PIEN(liLn), "PISI":Pred_PISI(liLn), \
           "PIAL":Pred_Pinus(liLn), "PIJE":Pred_Pinus(liLn), \
           "PIMO3":Pred_Pinus(liLn), "PICO":Pred_PICO(liLn), \
           "PILA":Pred_PILA(liLn), "PIPO":Pred_PIPO(liLn), \
           "TSHE":Pred_TSHE(liLn), "TSME":Pred_TSME(liLn), \
           "JUOC":Pred_JUOC(liLn), "TABR":Pred_TSHE(liLn), \
           "ALRU2":Pred_ALRU2(liLn), "ACCI":Pred_SMBGr(liLn), \
           "ACGL":Pred_SMBGr(liLn), "ACMA3":Pred_ACMA3(liLn), \
           "CONU4":Pred_ACMA3(liLn), "ALRH2":Pred_AACWGr(liLn), \
           "SASC":Pred_AACWGr(liLn), "SALIX":Pred_AACWGr(liLn), \
           "ARME":Pred_ARME(liLn), "BEPA":Pred_BEPA(liLn), \
           "BEPAC":Pred_BEPA(liLn), "CHCH7":Pred_CHCH7(liLn), \
           "FRLA":Pred_MHGr(liLn), "PREM":Pred_MHGr(liLn), \
           "PRVI":Pred_MHGr(liLn), "PRUNU":Pred_MHGr(liLn), \
           "LIDE3":Pred_LIDE3(liLn), "POBAT":Pred_POBAT(liLn), \
           "POTR5":Pred_POTR5(liLn), "QUCH2":Pred_QUCH2(liLn), \
           "QUGA4":Pred_QUGA4(liLn), "QUKE":Pred_QUKE(liLn), \
           "UMCA":Pred_UMCA(liLn)}
try: li_pred = di_eqns.get(liLn[2])

下面是一个列表(文本文件中的一行),当该键转到错误的函数(它转到Pred_PSME)时,它是从中获取的:

^{pr2}$

有人知道为什么会发生这种情况,以及如何解决它吗?如果您还需要其他信息,请告诉我。另外,我愿意为这个问题提供一个更好的名字。在

附录: 对不起,我本来没有把这个问题弄清楚。我仍然是python的初学者,对堆栈溢出还不熟悉;我不知道它是含糊不清的,我认为我们应该尽可能简洁地提出问题,不相关的细节是不可取的。在

这是程序的目标,从一个文件中读取行,每一行是从多个森林资源清册图中的一棵树的测量值,并对每一行,在由行中的前几个值表示的树上运行特定物种的方程,然后将每个图中所有树的方程结果相加。在

上面的代码I部分从行中读取第三个值,即行中表示的树的物种代码,并将该行传递给包含该树种的特定方程式的函数。在

根据我已经得到的答案,听上去像是当阅读上面的字典定义时,它会遍历列出的每个函数。我想要一些基本上能像select case在其他语言中一样的东西。我从另一个堆栈溢出问题的问答中得到了使用字典和get方法的想法。在

我只想在每次程序循环到新行时运行与行列表中的物种代码相匹配的函数。我注意到的是,这个字典似乎把行传递给了错误的函数,因为我在Pred_PSME函数中放了一个捕捉错误的代码位,它在出现错误时打印行值(在计算Pred_PSME中的一个等式值时也不断出现错误,这就是我添加调试代码的原因),它打印了上面包含的行。在

也许我误解了满是函数名的字典是怎么工作的。我想我的问题是,编写代码将元素列表以一行的形式发送到与liLn[2]中给定的物种代码相匹配的函数?在

在另一种语言中,您将对liLn[2]的值使用select case,每个大小写都是字典中列出的键之一,每个大小写的命令是函数中的命令,其名称列在字典的值中。在

以下是指向字典的代码以及字典的更多上下文:

def Main():
    srcf = open(bkp, 'r')
    old_fcid = 0
    li_fBQI = []
    i = 0
    for line in srcf:
        liLn = line.split(',')
        liLn = stripquotes(liLn)
        #Check if it's the first line, if so, jump to next line.
        if len(liLn) < 2: continue
        if HdrLine(liLn[:2]): continue
        fcid = liLn[1]
        #Check line fcid against last fcid
        if old_fcid != 0 and fcid != old_fcid:
            #Write the FCID BQI tallies to file
            Write_fBQIs(old_fcid, li_fBQI)
            #Reset FCID BQI tallies
            li_fBQI = []
        old_fcid = fcid
        #Calc BQI's for the tree
        li_tBQI = BQI_Calc(liLn)
        #Add tree BQI's to the FCID tallies
        li_fBQI = AddBQI(li_tBQI, li_fBQI)
        if i % 1000 == 0: print 'Finished line #' + str(i)
        i += 1
    #ADD: Write last FCID's BQI's to file
    Write_fBQIs(old_fcid, li_fBQI)
    srcf.close()

def BQI_Calc(liLn):
    di_eqns = {"PSME": Pred_PSME(liLn), "ABAM":Pred_ABAM(liLn), \
               "ABCO":Pred_Abies(liLn), "ABGR":Pred_Abies(liLn), \
               "ABLA":Pred_Abies(liLn), "ABMA":Pred_Abies(liLn), \
               "ABSH":Pred_Abies(liLn), "ABPR":Pred_ABPR(liLn), \
               "CADE27":Pred_Cedar(liLn), "CHLA":Pred_Cedar(liLn), \
               "CHNO":Pred_Cedar(liLn), "THPL":Pred_Cedar(liLn), \
               "LALY":Pred_LALY(liLn), "LAOC":Pred_LAOC(liLn), \
               "PIEN":Pred_PIEN(liLn), "PISI":Pred_PISI(liLn), \
               "PIAL":Pred_Pinus(liLn), "PIJE":Pred_Pinus(liLn), \
               "PIMO3":Pred_Pinus(liLn), "PICO":Pred_PICO(liLn), \
               "PILA":Pred_PILA(liLn), "PIPO":Pred_PIPO(liLn), \
               "TSHE":Pred_TSHE(liLn), "TSME":Pred_TSME(liLn), \
               "JUOC":Pred_JUOC(liLn), "TABR":Pred_TSHE(liLn), \
               "ALRU2":Pred_ALRU2(liLn), "ACCI":Pred_SMBGr(liLn), \
               "ACGL":Pred_SMBGr(liLn), "ACMA3":Pred_ACMA3(liLn), \
               "CONU4":Pred_ACMA3(liLn), "ALRH2":Pred_AACWGr(liLn), \
               "SASC":Pred_AACWGr(liLn), "SALIX":Pred_AACWGr(liLn), \
               "ARME":Pred_ARME(liLn), "BEPA":Pred_BEPA(liLn), \
               "BEPAC":Pred_BEPA(liLn), "CHCH7":Pred_CHCH7(liLn), \
               "FRLA":Pred_MHGr(liLn), "PREM":Pred_MHGr(liLn), \
               "PRVI":Pred_MHGr(liLn), "PRUNU":Pred_MHGr(liLn), \
               "LIDE3":Pred_LIDE3(liLn), "POBAT":Pred_POBAT(liLn), \
               "POTR5":Pred_POTR5(liLn), "QUCH2":Pred_QUCH2(liLn), \
               "QUGA4":Pred_QUGA4(liLn), "QUKE":Pred_QUKE(liLn), \
               "UMCA":Pred_UMCA(liLn)}
    try:
        li_pred = di_eqns.get(liLn[2])
    except:
        print '\n\n', 50*'-', 'ERROR: Couldn\'t find equations for the spp',\
              'code:', liLn[2]

    #Calc derivative quantities

    .....and the function continues from there

下面是字典中列出的函数的一个示例。普雷德是我上面提到的那个。在stem bark(sb)计算中不断出现错误,因此我添加了一些调试代码,这就是为什么我发现它是发送到PIEN树的,这就是为什么我开始这个问题:

def Pred_PSME(liLn):
    dbh = float(liLn[6])
    fol = exp(log(float(liLn[19])) + pqty(.0627, 123))
    lbr = exp((-3.6941 + 2.1382*log(dbh)) + pqty(.057, 123))
    dbr = exp((-3.529 + 1.7503*log(dbh)) + pqty(.079, 85))
    sw = exp(log(float(liLn[20])) + pqty(.0311, 99))
    try:
        sb = exp(log(float(liLn[21])) + pqty(.0324, 99))
    except:
        Badtree(liLn)
        print dbh, liLn
    ts = exp(-3.0396 + 2.5951*log(0.865 * mtd) + pqty(.0311, 99)) +\
         exp(-4.3103 + 2.4300*log(0.865 * mtd) + pqty(.0324, 99))
    br = lbr +dbr
    agb_nf = br + sw + sb
    agb = agb_nf + fol
    return [fol, br, sw, sb, agb, agb_nf, ts]

def Pred_ARME(liLn):
    dbh = float(liLn[6])
    agb_nf = float(liLn[27]) + tvariate(57) * 1.23 * (1 + 1/60)**(1/2)
    agb = agb_nf / (1 - folpct)
    fol = agb - agb_nf
    br = sw = sb = ts = 0
    return [fol, br, sw, sb, agb, agb_nf, ts]

我希望这能让事情变得更清楚。如果还有问题请告诉我。顺便说一句,大家说“代码味道”是什么意思?另外,我在格式化这个站点的文本时遇到了一些问题。有没有一种方法可以识别这个站点上的代码块4个空格而不需要手动在每一行添加4个空格?谢谢。在


Tags: 函数代码log字典错误lipredcedar
2条回答

如果diu eqns设置为一次,那么dict中的值将取决于设置时的liLn的值。

如果在每个输入记录中设置一次diu-eqns,那么效率不高。创建一个包含49个词条的字典是浪费,但是每个记录一个词条也是可以忍受的。但在这种情况下更糟:它计算所有49个函数调用,然后只计算一个结果。那太浪费了。如果这些函数中的任何一个有副作用,例如它们改变了全局状态,那么除了总效率问题之外,你还有一个总的逻辑问题。在

我建议您设置一次dict,如下所示:

di_eqns = {
    # for better legibility, arrange the following lines in alphabetical key order;
    # then a duplicate key entry is easier to see.
    "PSME": Pred_PSME,
    "ABAM": Pred_ABAM,
    "ABCO": Pred_Abies,
    "ABGR": Pred_Abies,
    # et cetera
    }

对每一张唱片都要这样做:

^{pr2}$

如果问题还没有解决,打印语句应该可以帮助您找出原因。如果您需要更多帮助,您需要向我们展示PIEN函数和PSME函数的代码,以及主线的代码。在

编辑更多代码卫生:刚刚看了一下“从文本文件行”。。。{you should looks to your module looks^而不是使用cd2>来读取文件

for guff in f:
    liLn = guff.split(',')

我相信问题是,当您创建它时,di_eqns字典中所有看起来是函数调用的Pred_XXXX(liLn)值都被它们的返回值所取代,当然这取决于构造时的liLn值,而不是调用get()。在

如下所示会延迟对Pred_XXXX()函数的调用。基本上,它首先根据文本文件中列表中的第三项查找要调用的函数,然后将整个列表传递给函数:

di_eqns = {"PSME":Pred_PSME, "ABAM":Pred_ABAM,
           "ABCO":Pred_Abies, "ABGR":Pred_Abies,
           "ABLA":Pred_Abies, "ABMA":Pred_Abies,
           "ABSH":Pred_Abies, "ABPR":Pred_ABPR,
           "CADE27":Pred_Cedar, "CHLA":Pred_Cedar,
           "CHNO":Pred_Cedar, "THPL":Pred_Cedar,
           "LALY":Pred_LALY, "LAOC":Pred_LAOC,
           "PIEN":Pred_PIEN, "PISI":Pred_PISI,
           "PIAL":Pred_Pinus, "PIJE":Pred_Pinus,
           "PIMO3":Pred_Pinus, "PICO":Pred_PICO,
           "PILA":Pred_PILA, "PIPO":Pred_PIPO,
           "TSHE":Pred_TSHE, "TSME":Pred_TSME,
           "JUOC":Pred_JUOC, "TABR":Pred_TSHE,
           "ALRU2":Pred_ALRU2, "ACCI":Pred_SMBGr,
           "ACGL":Pred_SMBGr, "ACMA3":Pred_ACMA3,
           "CONU4":Pred_ACMA3, "ALRH2":Pred_AACWGr,
           "SASC":Pred_AACWGr, "SALIX":Pred_AACWGr,
           "ARME":Pred_ARME, "BEPA":Pred_BEPA,
           "BEPAC":Pred_BEPA, "CHCH7":Pred_CHCH7,
           "FRLA":Pred_MHGr, "PREM":Pred_MHGr,
           "PRVI":Pred_MHGr, "PRUNU":Pred_MHGr,
           "LIDE3":Pred_LIDE3, "POBAT":Pred_POBAT,
           "POTR5":Pred_POTR5, "QUCH2":Pred_QUCH2,
           "QUGA4":Pred_QUGA4, "QUKE":Pred_QUKE,
           "UMCA":Pred_UMCA}

try: li_pred = di_eqns.get(liLn[2])(liLn)

然而,如果没有关于你要完成的事情的额外信息,很难提出任何明确的建议。。。在

相关问题 更多 >