Python 有条件地创建列表列表

Python 有条件地创建列表列表,python,Python,我不知道我是否用最好的方式表达了这一点,但本质上我想创建一个基于不同条件的列表列表 我使用ElementTree读入一些XML数据,在解析它之后,我遍历树并将所有标记放在名为tags的列表中,将它们的值放在名为vals的列表中 在我的标记列表中,有几个句子标记,我想将字典的键和相应的值附加到列表中,并生成值 我的标记列表、它们对应的值和句子标记如下所示 tags = ['irrel', 'TAG_ONE', 'TAG_ONE', 'TAG_TWO', 'TAG_ONE', 'TAG_TWO',

我不知道我是否用最好的方式表达了这一点,但本质上我想创建一个基于不同条件的列表列表

我使用ElementTree读入一些XML数据,在解析它之后,我遍历树并将所有标记放在名为
tags
的列表中,将它们的值放在名为
vals
的列表中

在我的标记列表中,有几个句子标记,我想将字典的键和相应的值附加到列表中,并生成值

我的标记列表、它们对应的值和句子标记如下所示

tags = ['irrel', 'TAG_ONE', 'TAG_ONE', 'TAG_TWO', 'TAG_ONE', 'TAG_TWO', 'irrel']

vals = ['not_rel', 1, 2, 5, 3, 6, 'not_rel']

sent_tags = ['TAG_ONE', 'TAG_TWO']
我的理想输出是
tags_dict={'TAG_ONE':[1,2,3],'TAG_TWO':[5,6]}
,这是我使用下面的代码实现的

sent_vals = list()

# Make a list of all TAG_ONE values and append list to sentence values list
tag_one = list()
tag_one_locs = [i for i, x in enumerate(tags) if x == 'TAG_ONE']
for t in tag_one_locs:
    tag_one.append(vals[t])
sent_vals.append(tag_one)

# make a list of all TAG_TWO values and append list to sentence values list
tag_two = list()
tag_two_locs = [i for i, x in enumerate(tags) if x == 'TAG_TWO']
for tt in tag_two_locs:
    tag_two.append(vals[tt])
sent_vals.append(tag_two)

tags_dict = dict(zip(sent_tags, sent_vals))

然而,这是相当丑陋的,仅仅复制和粘贴代码一百万次是不切实际的,因为我的真实数据有大约70个句子标签。在如何将代码简化为某种列表理解(或其他内容)方面,我还是一片空白。

好吧,您可以使用
集合将其大大简化。defaultdict(list)

  • 将标签和值压缩在一起
  • 如果标记匹配其中一个有趣的标记,则添加到字典
像这样:

import collections

tags = ['irrel', 'TAG_ONE', 'TAG_ONE', 'TAG_TWO', 'TAG_ONE', 'TAG_TWO', 'irrel']

vals = ['not_rel', 1, 2, 5, 3, 6, 'not_rel']

sent_tags = {'TAG_ONE', 'TAG_TWO'}  # set is preferred when a lot of elements (faster "in" lookup)

tags_dict = collections.defaultdict(list)

for tag,val in zip(tags,vals):
    if tag in sent_tags:
        tags_dict[tag].append(val)

print(dict(tags_dict))  # convert to dict just to print
结果:

{'TAG_TWO': [5, 6], 'TAG_ONE': [1, 2, 3]})
口述理解:

{sent_tag: [vals[ind] for ind, tag in enumerate(tags) if tags[ind] == sent_tag] for sent_tag in sent_tags}
如果理解结构让您感到困惑,可以这样思考代码:

output = {}
for sent_tag in sent_tags:
    val_list = []

    for ind, tag in enumerate(tags):
        if tags[ind] == sent_tag:
            val_list.append(vals[ind])

    output.update({sent_tag: val_list})
无论哪种方式:

您的输出将是:

{'TAG_ONE': [1, 2, 3], 'TAG_TWO': [5, 6]}

首先不要调用变量
tag\u one\u loc
tag\u two\u loc
,而是使用
tag\u one
等创建口述。。。作为钥匙。然后你可以在标签上循环。或者只使用相同的变量,循环
标签
VAL
丢失。我认为这可以在一行理解中完成,但提供像wjandrea评论的最小数据。在reslovedI发布之前暂缓发布,这会建议你彻底澄清这个问题——你得到了什么样的数据,你希望得到什么?目前,有相当多的未初始化变量,您的目标并不完全清楚,但这个问题是完全可以解决的。你可能会发现这很有用:。这很完美,正是我想要的。谢谢你的帮助!这也是一个很好的选择,我很欣赏对理解结构的解释。