如何在Python的嵌套列表中标记匹配项

时间:2018-07-09 14:47:47

标签: python list loops nested

这里是Python的新手。

我目前有一个嵌套列表的列表。我正在尝试标记每个从0-25开始的子列表。 但是,如果两个子列表相同,则它们应具有相同的标签。

例如:

label_list = [['AH0'], ['AA1', 'K', 'S'], ['AH0', 'N', 'T'], ['AA1', 'K', 'S'], ['IH0', 'N'], ['AA1', 'K', 'S']]

输出应为[0, 1, 2, 1, 4, 1]

因为第二,第四和第六个子列表相同。其余子列表应仅以连续的数字顺序标记。 我知道我需要使用一个循环,但是我很困惑,任何人都对如何解决这个问题有任何建议? 谢谢。

2 个答案:

答案 0 :(得分:5)

您可以使用字典:

label_list = [['AH0'], ['AA1', 'K', 'S'], ['AH0', 'N', 'T'], ['AA1', 'K', 'S'], ['IH0', 'N'], ['AA1', 'K', 'S']] 
count = 0
d = {}
for i in label_list:
  if tuple(i) not in d:
    d[tuple(i)] = count
  count += 1

final_result = [d[tuple(i)] for i in label_list]

输出:

[0, 1, 2, 1, 4, 1]

编辑:以上解决方案假定标签是根据唯一值的首次出现的索引生成的。但是,如果需要一般的增量,并且要根据看到的唯一元素的数量来创建标签,则可以count移至for循环内:

if tuple(i) not in d:
  d[tuple(i)] = count
  count += 1

然后,输出为[0, 1, 2, 1, 3, 1]

也可以使用列表理解,尽管效率不高:

c = iter(range(len(label_list)))
new_d = {tuple(a):i for i, a in reversed(list(enumerate(label_list)))}
final_result = [next(c) if a not in label_list[:i] else new_d[tuple(a)] for i, a in enumerate(label_list)]

输出:

[0, 1, 2, 1, 3, 1]

答案 1 :(得分:0)

这里只是一线,只是为了好玩:

 [dict( map( reversed, enumerate( set( map(tuple, label_list)))))[tuple(item)] for item in label_list]

缺点(除了不可读之外)是,它创建字典的次数与label_list中条目的次数相同。

要解释其工作原理,请从内而外阅读:

map(tuple, label_list)将(或“映射”)元组函数应用于label_list的每个元素,以便以后每个元素都可以用作字典中的键(python列表不能是字典键)

set( map(tuple, label_list))在label_list中创建了一组所有唯一元素,我们需要这样做,因为您希望每个唯一条目都具有唯一标签

enumerate( set( map(tuple, label_list)))枚举是一个将某些列表作为输入并为列表的每个元素返回唯一(按顺序)整数的函数。因此,您得到的是一个像这样的元组列表[[0,element_0),(1,element_1)...]

map( reversed, enumerate( set( map(tuple, label_list))))会颠倒上述列表中的元素,因此,当我们在下一步中创建字典时,这些元素将是键而不是整数。所以我们得到[[element_0,0),(element_1,0)...]

dict( map( reversed, enumerate( set( map(tuple, label_list)))))只需简单地获取上一步中的元组列表,然后从中创建一个字典,就可以像访问其他任何字典一样使用它们的键(即使用dictionary[element]语法)。

该行的其余部分与其他任何列表理解一样。迭代原始的label_list并访问我们创建的字典以获得与每个元素关联的唯一编号。