检查元组列表中是否有字符串,然后访问它以打印它

时间:2014-07-12 23:35:02

标签: python list tuples

我想打印html标签ID,如果它有id。如果标签没有id而是类,我希望它打印该类。如果没有id或类,我希望它打印标签名称(img,h1等)。它只需要一个打印,如id或class或tag,但不是全部。它需要始终支持第一个id,然后是类,然后是标记名称,但只显示其中一个。它用于输出sass(如css)模板。

我需要查看是否' id'在这个元组列表中(它是):

[('class', 'title'), ('id', 'donkey'), ('src', 'images/DonkeyKongLogo.png')]

该列表名为attrs。这是我的代码,看看是否' id'在attrs:

它会检查第一个元组并查看'类'和' title'但没有' id'这是在下一个元组中,所以它转到下一个if语句(永远不会找到' id')。任何帮助赞赏。谢谢。

 def handle_starttag(self, tag, attrs):
    if attrs != []:
        for attr in attrs:
            if ('id' in attr):
                id = attr.index('id')
                self.the_file.writelines(self.indent * self.getpos()[1] + '#' + attr[id+1] + ' {' +'\n')
                self.pos = self.getpos()[1]
                break
            elif ('class' in attr):
                clas = attr.index('class')
                self.the_file.writelines(self.indent * self.getpos()[1] + "." + attr[clas+1] + " {"+'\n')
                self.pos = self.getpos()[1]
                break
            else:
                self.the_file.writelines(self.indent * self.getpos()[1] + tag + " {"+'\n')
                self.pos = self.getpos()[1]
                break

5 个答案:

答案 0 :(得分:1)

您可以使用简单的列表理解:

>>> attrs = [('class', 'title'), ('id', 'donkey'), ('src', 'images/DonkeyKongLogo.png')]
>>> 'id' in [item for sub in attrs for item in sub]
True
>>> 

要打印'id''donkey')的后续值,请执行以下操作:

>>> attrs = [('class', 'title'), ('id', 'donkey'), ('src', 'images/DonkeyKongLogo.png')]
>>> [item[1] for item in attrs if item[0] == 'id'][0]
'donkey'

答案 1 :(得分:1)

元组列表总是由名称 - 值对组成;只需使用带有元组解包的for循环:

def handle_starttag(self, tag, attrs):
    for name, value in attrs:
        if name == 'id':
            value = '#' + value
        elif name == 'class':
            value = '.' + value
        elif:
            value = tag

        self.the_file.writelines(self.indent * self.getpos()[1] + value + ' {\n')
        self.pos = self.getpos()[1]

这会在attrs中处理每个元组,而不仅仅是第一个(使用break关键字的意思)。如果你真的只想处理第一个,那么使用:

if attrs:
    name, value = attrs[0]
    if name == 'id':
        value = '#' + value
    elif name == 'class':
        value = '.' + value
    elif:
        value = tag
    self.the_file.writelines(self.indent * self.getpos()[1] + value + ' {\n')
    self.pos = self.getpos()[1]

如果您需要测试某些属性,则唯一的选择是首先扫描idclass属性;可能有多个这样的键值对,看起来你只想匹配第一次出现。

幸运的是,dict对象可以轻松实现,但反向键值对,以便只有第一个 id或使用class键值对(按相反的顺序,它们会覆盖任何额外的类或id键值对):

attrs_dict = dict(reversed(attrs))

if 'id' in attrs_dict:
    value = '#' + attrs_dict['id']
elif 'class' in attrs_dict:
    value = '.' + attrs_dict['class']
else:
    value = tag

self.the_file.writelines(self.indent * self.getpos()[1] + value + ' {\n')
self.pos = self.getpos()[1]

现在代码选择第一个id属性(如果存在),否则使用第一个class属性,否则使用标记名称。

答案 2 :(得分:0)

你为什么不创建字典?

d = dict([('class', 'title'), ('id', 'donkey'), ('src', 'images/DonkeyKongLogo.png')])

然后,

In [4]: 'id' in d
Out[4]: True

不确定你到底想要什么,但我猜你可以这样做:

In [5]: if 'id' in d: print d['id']
donkey

甚至,

In [6]: if 'id' in d: print d['src']
images/DonkeyKongLogo.png

In [7]: if d['id'] == 'donkey': print d['src']
images/DonkeyKongLogo.png

在您的代码中没有得到您想要的内容......

编辑:

您显示的代码应写为:

def handle_starttag(self, tag, attrs):
    if attrs != []:
        d = dict(attrs)             

        # some examples of the dictionary use ...

        if 'id' in d: print d['id']
        if ('id' in d) and (d['id'] == 'donkey') : print d['url']

答案 3 :(得分:0)

将所有子元组展平为单个列表并搜索属性,然后搜索其值:

import itertools

attrs = [('class', 'title'), ('id', 'donkey'), ('src', 'images/DonkeyKongLogo.png')]

dump = [y for y in itertools.chain(*attrs)] 
#dump = ['class', 'title', 'id', 'donkey' , 'src', 'images/DonkeyKongLogo.png']

if 'id' in dump: value = dump[dump.index('id') + 1]
elif 'class' in dump: value = dump[dump.index('class') + 1]
else: value = dump[1]

print value

这假设如果没有idclass属性,则该属性将只包含一个包含tagvalue

的元组

答案 4 :(得分:0)

def handle_starttag(self, tag, attrs):
    id=None
    clas=None
    for attr,value in attrs:
        if attr=='id':
            id='#'+value
            break    # Only since highest priority
        elif attr=='class':
            clas = '.'+value
    value=id or clas or tag
    self.the_file.writelines(self.indent * self.getpos()[1] + value + ' {' +'\n')
    self.pos = self.getpos()[1]

这使用了or的快捷行为以及非空字符串的真实性和无的虚假性。它不会考虑多个类,但只会选择最后一个(在elif添加and not clas以获得第一个)。类似的方法是将属性列表转换为字典,但这也只保存每个属性的最后一个,在这种情况下,我们希望以各种方式处理它们(添加句点或井号)。

另一种变体是使用reduce来定义优先级函数:

def prio(cur, (attr,value)):
    if attr=='id':
        return '#'+value
    elif attr=='class' and cur[0] not in '#.':
        return '.'+value  # found a class, and had neither class nor id
    else:
        return cur

然后选择变得相当简单:

In [10]: reduce(prio,[('class', 'title'), ('id', 'donkey')],'img')
Out[10]: '#donkey'
In [11]: reduce(prio,[('unknown','irrelevant')],'img')
Out[11]: 'img'
In [12]: reduce(prio,[('class','foo')],'img')
Out[12]: '.foo'
In [13]: reduce(prio,[('class','foo'),('class','bar')],'img')
Out[13]: '.foo'