使用Python中的另一个元组过滤元组

时间:2016-02-22 16:42:38

标签: python list tuples

我有一个使用zip函数创建的元组列表。 zip汇集了四个列表:narrativesubjectactivityfiler,每个列表只是0和1的列表。假设这四个列表看起来像这样:

narrative = [0, 0, 0, 0]
subject = [1, 1, 0, 1]
activity = [0, 0, 0, 1]
filer = [0, 1, 1, 0]

现在,我zip将它们放在一起得到一个布尔值列表,指示它们中是否有True

ny_nexus = [True if sum(x) > 0 else False for x in zip(narrative, subject, activity, filer)]

我现在遇到的问题是获得第二个元组列表,如果在迭代期间它具有1,则返回变量的名称。我想它看起来像这样:

variables = ("narrative", "subject", "activity", "filer")
reason = [", ".join([some code to filter a tuple]) for x in zip(narrative, subject, activity, filer)]

我无法弄清楚我是怎么做到这一点的。我想要的输出看起来像这样:

reason
# ["subject", "subject, filer", "filer", "subject, activity"]

我对Python有点新手,所以如果解决方案很简单,我会道歉。

4 个答案:

答案 0 :(得分:3)

将元组存储在字典中以获得更清晰的解决方案:

tups = {'narrative': narrative,
        'subject': subject,
        'activity': activity,
        'filer': filer}

解决方案:

reason = [', '.join(k for k, b in zip(tups, x) if b) for x in zip(*tups.values())]

也可以使用itertools.compress

编写
from itertools import compress
reason = [', '.join(compress(tups, x)) for x in zip(*tups.values())]

上述解决方案不保留元组的顺序,例如他们可以返回类似

的内容
['subject', 'filer, subject', 'filer', 'activity, subject']

如果您需要保留订单,请使用collections.OrderedDict,如下所示:

from collections import OrderedDict

tups = OrderedDict([
    ('narrative', narrative),
    ('subject', subject),
    ('activity', activity),
    ('filer', filer)
])

# The result is ['subject', 'subject, filer', 'filer', 'subject, activity']

编辑: 不涉及词典的解决方案:

from itertools import compress
reason = [', '.join(compress(variables, x))
          for x in zip(narrative, subject, activity, filer)]

如果zip(...)调用不再适合一行,请考虑使用词典。

答案 1 :(得分:1)

使用if __name__ == "__main__"基本上转置矩阵(等长的列表列表构成矩阵)。然后,通过这些枚举来查找标志为真的位置zip(narrative, subject, activity, filer)并索引相应的变量。

n

要查看转置:

narrative = [0, 0, 0, 0]
subject = [1, 1, 0, 1]
activity = [0, 0, 0, 1]
filer = [0, 1, 1, 0]
variables = ("narrative", "subject", "activity", "filer")
# ========================================================

new_list = [[variables[n] for n, flag in enumerate(indicators) if flag] 
            for indicators in zip(narrative, subject, activity, filer)]
>>> new_list
[['subject'], ['subject', 'filer'], ['filer'], ['subject', 'activity']]

答案 2 :(得分:0)

您可以使用理解语法的过滤方面来获取 只有当相应的标志为True时,您的可变英文名称:

variables = ("narrative", "subject", "activity", "filer")
[tuple (name for flag, name in zip(x, variables) if x)  for x in zip(narrative, subject, activity, filer)]

也就是说,你的方法有些可疑 - 你很可能(远)更好地使用面向对象的方法,而不是试图为每个主题手动协调独立的变量序列。

答案 3 :(得分:0)

    narrative = [0, 0, 0, 0]
    subject = [1, 1, 0, 1]
    activity = [0, 0, 0, 1]
    filer = [0, 1, 1, 0]
    variables = ("narrative", "subject", "activity", "filer")
    ny_nexus = [True if sum(x) > 0 else False for x in zip(narrative, subject, activity, filer)]
    output = []
    [[output.append(variables[j]) if t==1 else None for j,t in enumerate(x)] for x in zip(narrative, subject, activity, filer)]
    print ny_nexus
    print output

当然,您可以在不使用列表推导的情况下执行以下操作:

    narrative = [0, 0, 0, 0]
    subject = [1, 1, 0, 1]
    activity = [0, 0, 0, 1]
    filer = [0, 1, 1, 0]
    variables = ("narrative", "subject", "activity", "filer")
    ny_nexus = [True if sum(x) > 0 else False for x in zip(narrative, subject, activity, filer)]
    output = []
    for x in zip(narrative, subject, activity, filer):
        for j,t in enumerate(x):
            output.append(variables[j])
    print ny_nexus
    print output