如何保持重复元素的索引不变

时间:2012-07-15 08:01:31

标签: python map indexing enumerate

这是一个输入列表:

['a', 'b', 'b', 'c', 'c', 'd']

我期望的输出应该是:

[[0, 'a'], [1, 'b'],  [1, 'b'], [2, 'c'], [2, 'c'], [3, 'd']]

我尝试使用map()

>>> map(lambda (index, word): [index, word], enumerate([['a', 'b', 'b', 'c', 'c', 'd']])
[[0, 'a'], [1, 'b'], [2, 'b'], [3, 'c'], [4, 'c'], [5, 'd']]

如何获得预期结果?

编辑:这不是排序列表,每个元素的索引只在遇到新元素时才会增加

4 个答案:

答案 0 :(得分:6)

>>> import itertools
>>> seq = ['a', 'b', 'b', 'c', 'c', 'd']
>>> [[i, c] for i, (k, g) in enumerate(itertools.groupby(seq)) for c in g]
[[0, 'a'], [1, 'b'], [1, 'b'], [2, 'c'], [2, 'c'], [3, 'd']]

答案 1 :(得分:4)

[
    [i, x]
    for i, (value, group) in enumerate(itertools.groupby(['a', 'b', 'b', 'c', 'c', 'd']))
    for x in group
]

答案 2 :(得分:1)

听起来你想根据词典排序对术语进行排名。

input = ['a', 'b', 'b', 'c', 'c', 'd']
mapping = { v:i for (i, v) in enumerate(sorted(set(input))) }
[ [mapping[v], v] for v in input ]

请注意,这也适用于未排序的输入。

如果您的修正案建议您想根据首次出场顺序对项目进行编号,则需要采用不同的方法。以下是短暂而甜蜜的,尽管是在进攻性的hacky:

[ [d.setdefault(v, len(d)), v] for d in [{}] for v in input ]

答案 3 :(得分:1)

列表排序时使用groupby(参见jamylak回答);如果没有,只需遍历列表并检查您是否已经看过这封信:

a = ['a', 'b', 'b', 'c', 'c', 'd']
result = []
d = {}
n = 0
for k in a:
  if k not in d:
     d[k] = n
     n += 1
  result.append([d[k],k])

这是最有效的解决方案;它只需要O(n)时间。

未排序列表的使用示例:

[[0, 'a'], [1, 'b'], [1, 'b'], [2, 'c'], [2, 'c'], [3, 'd'], [0, 'a']]

如您所见,此处的项目顺序与输入列表中的顺序相同。

首先对列表进行排序时,需要额外的O(n * log(n))。