将for循环和if语句转换为字典理解

时间:2019-07-31 14:36:13

标签: python dictionary list-comprehension

有人告诉我列表理解优于嵌套的for循环。

在我学习的Python课程中,我们学习了for和while循环,而不是列表或字典理解。现在,我正在尝试改善代码。我通常通过首先在嵌套循环中编写所需的内容,然后将其“翻译”为列表推导来执行此操作。

在这种情况下,我正在尝试构建一个结构如下的字典:

{chemical_name_1 :
{field_1: xxxx
field_2: yyyy
field_3: zzzz}
{chemical_name_2 :
{field_1: xxxy
field_2: yyyz
field_3: zzzx}
...}

这是带有if语句的for循环,可以正常工作。

wantedfields= ["ADI","General human health issues","CAS RN"]

results={}
for p in rand_links.keys():
    tableText = [td.text.strip() for td in pesticideSoup[p].find_all("td", recursive=True)]
    resd={}
    for n,t in enumerate(tableText):
        for field in wantedfields:
            if field in t:
                 resd[t]=tableText[n+1]
            results[p]=resd

杀虫剂汤是一本词典,源于美丽的汤。它的结构如下:

{chemical_name_1 :
<!DOCTYPE html>
<html>
<head>some HTML code</head>,
chemical_name_2 :
<!DOCTYPE html>
<html>
<head>some HTML code</head>
}

并且rand_links也是一本字典,只是以化学名称为键,URL为值。

这是我尝试将嵌套的for循环转换为字典理解:

results = {p: {t:tableText[n+1] if field in t} for field in wantedfields for t in [td.text.strip() for td in pesticideSoup[p].find_all("td", recursive=True)] for p in rand_links.keys()}

我希望获得与嵌套的for循环相同的结果,但是出现语法错误。

请您

  • 告诉我我要去哪里哪里,并帮助我纠正以上问题

  • 建议我如何学习以变得更好。

  • 您曾经使用什么方法和资源来胜任这项特定技能

任何提示和帮助表示赞赏!

2 个答案:

答案 0 :(得分:1)

  

有人告诉我列表理解优于嵌套for循环。

与任何与样式相关的内容一样,这在某种程度上是个人喜好问题。对于代码而言,可读性是一个重大好处。

foo = []
for thing in things:
    foo.append(thing + 5)

我认为上面的内容不如

foo = [thing + 5 for thing in things]

因此,在这种情况下,理解力将是我的偏好。但是,对于您的示例,理解力

results = {p: {t:tableText[n+1] if field in t} for field in wantedfields for t in [td.text.strip() for td in pesticideSoup[p].find_all("td", recursive=True)] for p in rand_links.keys()}

是(IMO)可怕的难以理解的混乱。您是否希望有人编写该代码供您阅读?使用多行循环的“解压缩”版本可能会明显提高可读性,因此,尽管它占用了更多的代码行,但这仍是我的偏爱。

代码中的“更好”和“更差”是主观的-它取决于您的需求。对于python非常适合的任务,代码可读性通常比通过某种方式“优化”代码所获得的任何优势都要有用。

答案 1 :(得分:1)

您必须从大事情转向小事情-在dict理解中重新排列您的“ for”,反之亦然。 ;)

此外,对于嵌套字典,请执行另一种理解,否则,如果您的代码可行,则最多将获得单元素字典。

请记住,您可以在理解内使用普通函数!您可以对单个事物作为函数进行一些解析,然后将fun(pesticideSoup[p])作为值!

为了可读性,可以将代码分成多行。

results = {p: {t:tableText[n+1] 
               for t in [td.text.strip() for td in pesticideSoup[p].find_all("td", recursive=True)]
               for field in wantedfields if field in t} 
           for p in rand_links.keys()}

^基本上就是那些修改后的代码。

它会中断,因为我不知道在这种情况下tableText的实际含义-实际上,我也不理解您原来的for n,t in enumerate(tableText),因为您正在用tableText填充子字典[n]:tableText [n + 1]在那里(如果需要tableText [n])?

但是此版本实际上是可读的,并且可能会更好地发现您可能造成的任何错误。 (或者做我提到的功能。)