python - 使用字典的 'get' 方法来选择大小写。为什么它总是选择错误的东西?

标签 python

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

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])

这是 key 从错误函数(它转到 Pred_PSME)中获取的列表(文本文件中的一行):

['1347189', '20571', 'PIEN', 'Picea engelmannii', 'Y', 'Y', '66.294',
 '0.3452', '35.7418', '', '5.0996', '0', '1', '1.1324', '3.2803', '2.3057',
 '16.7282', '5520.306', '127.30', '70.73', '92.10', '0.00', '5.68', '2.37',
 '7.25', '79.16', '76.79', '290.15', '219.41', '135.37', '0.00', '0.00',
 '951.78', '719.74', '259.68', '251.89', '444.05', '0.00', '0.00', '',
 '12.70', '10.16', '15.24', '0.02', '0.04', '0.19', '0.19', '0.00', '0.00',
 '0.42', '0.32', '0.11', '0.11\r\n']

有人知道为什么会发生这种情况以及如何解决它吗?如果您需要任何其他信息,请告诉我。此外,我愿意接受有关为这个问题取一个更好的名字的建议。

附录: 抱歉,我最初没有让这个问题更清楚。我仍然是 python 的初学者,也是 Stack Overflow 的新手;我不知道这是模棱两可的,我的印象是我们应该让我们的问题尽可能简洁,不相关的细节是不可取的。

这是程序的目标,从文件中读取行,每一行都是来自多个森林 list 地 block 之一的树的测量值,并且对于每一行,在由直线中的前几个值,然后将每个图中所有树的方程式结果相加。

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

根据我已经得到的答案,听起来好像在阅读上面的字典定义时,它贯穿了列出的每个函数。我想要的东西基本上可以做 select case 在其他语言中可以做的事情。我从 Stack Overflow 上的另一个问答中得到了使用字典和 get 方法的想法。

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

也许我误解了充满函数名称的字典是如何工作的。我想我的问题是,编写代码将一行中的元素列表发送到与 liLn[2]?

中给出的物种代码相匹配的函数

在另一种语言中,您可以对 liLn[2] 的值使用 select case,每个 case 都是字典中列出的键之一,以及用于每个 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

这是字典中列出的函数的示例。 Pred_PSME 就是我上面提到的那个。 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 个空格?谢谢。

最佳答案

我认为问题在于 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)

但是,如果没有关于您要完成的任务的额外信息,就很难提出任何明确的建议...

关于python - 使用字典的 'get' 方法来选择大小写。为什么它总是选择错误的东西?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5367300/

相关文章:

python - 如何将键值对分布在多个列上并基于另一列展平矩阵?

python - 简单但奇怪的 vstack/concatenate 问题 (python)

python - 尝试在Keras中加载顺序模型时出现“KeyError:0”

python - Django 员工用户仅管理他们自己创建的用户

python - 如何在 Google App Engine 柔性环境中运行 TensorFlow?

python - 修改python中的二叉树

python - 在 numpy 中查找第一个非零行

python - Django 1.5 : OperationalError in windows when running "python manage.py syncdb" using postgresql-psycopg2

python - Python 运算符重载到底是如何工作的?

python - 有没有办法在 Bokeh 图中拥有多个图例颜色文本?