这里是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]
因为第二,第四和第六个子列表相同。其余子列表应仅以连续的数字顺序标记。 我知道我需要使用一个循环,但是我很困惑,任何人都对如何解决这个问题有任何建议? 谢谢。
答案 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并访问我们创建的字典以获得与每个元素关联的唯一编号。