Python:根据元素对(子)列表进行操作

Python: Act upon (sub)list depending on elements

[我从 python 开始;抱歉,如果以下内容很愚蠢,但我整天都在思考这个问题,觉得我自己无法解决这个问题。]

我有一个这样的列表:

list = [['a', 'A', '10.0.0.2'], ['a', 'TXT', '1'], ['a', 'TXT', '2'], ['b', 'A', '10.10.10.10'], ['c', 'A', '10.0.0.3'], ['c', 'TXT', '3'], ['c', 'TXT', '4']]

此示例显示了包含七个子列表的列表,但可能有 n 个。

我想要实现的目标:每个唯一的 list[i][0](在这种情况下,'a'、'b'、'c')应该有 'A' 和'TXT'在相应的子列表中,所以在这个例子中,保留所有list[i][0] == 'a'list[i][0] == 'c',删除所有出现的list[i][0] == 'b'

我已经尝试了各种方法来实现这一点,但实际上没有什么可展示的,因为我缺少一个想法,如何做到这一点。

我做了什么:

获得唯一性 list[i][0]:

names = [list[i][0] for i in range(len(list))]

names_unique = list(set(names))

但是...如何进行?我想,像 for ... in ... 这样的东西应该可以解决问题?有人可以对此有所了解吗?将不胜感激!

编辑 1: 抱歉不清楚:'a'、'b' 和 'c' 只是任意值。我事先不知道这些,这是 dns 区域传输的输出。我想保留所有获得关联 A 和 TXT 记录的主机名(此处:'a'、'b'、'c'),并在没有 TXT 的情况下删除这些主机名。我不能硬编码任何名称,例如 'a'、b' 或 'c',因为这些会改变;相反,我正在尝试编写执行我在此处描述的内容的代码。

期望的输出:

list = [['a', 'A', '10.0.0.2'], ['a', 'TXT', '1'], ['a', 'TXT', '2'], ['c', 'A', '10.0.0.3'], ['c', 'TXT', '3'], ['c', 'TXT', '4']]

您可以尝试使用过滤器和 lambda 表达式。例如:

acceptable_elements = ['a','b']
filtered_list = filter(lambda sublist: (sublist[0] in acceptable_elements), my_list)

这将检查列表的所有元素,并且不会改变您的原始列表。如果您想检查整个列表中是否存在元素,我无法从您的示例中准确判断您是要检查第一个位置还是要检查整个列表:

acceptable_elements = ['a','b']
filtered_list = filter(lambda sublist: any([c in acceptable_elements for c in sublist]), my_list)

你可以这样做:

'define a function that checks if a key is valid or not'
def isValid(key, l):
    return all(_ in (x[1] for x in filter(lambda x:x[0] == key,l)) for _ in ['TXT','A'])

keys = list(set(x[0] for x in l))
keysValid = []
for key in keys: 
    if isValid(key, l): keysValid.append(key)

filtered_list = list(filter(lambda x: x[0] in keysValid, l))

所有这一切都是获取所有可能的密钥,然后将所有有效密钥添加到新列表中。然后它使用原始列表上的 filter 来检查密钥是否在有效密钥列表中。

这是一个丑陋的衬垫,您也可以使用它:

>>> l = [['a', 'A', '10.0.0.2'], ['a', 'TXT', '1'], ['a', 'TXT', '2'], ['b', 'A', '10.10.10.10'], ['c', 'A', '10.0.0.3'], ['c', 'TXT', '3'], ['c', 'TXT', '4']]
>>> #this monstrosity right here
>>> u = list(filter(lambda x: x[0] in filter(lambda key: all(_ in (x[1] for x in filter(lambda x:x[0] == key,l)) for _ in ['TXT','A']),set(li[0] for li in l)),l))
>>> u
[['a', 'A', '10.0.0.2'], ['a', 'TXT', '1'], ['a', 'TXT', '2'], ['c', 'A', '10.0.0.3'], ['c', 'TXT', '3'], ['c', 'TXT', '4']]

主要注意事项:这与您的原始问题有点无关,但不要使用 list 作为变量名。这将禁止对 python 的列表函数 list() 的任何调用,这在您使用 filter()/set() 时很有用,因为它们 return filter/set objects 而不是 list.