【问题标题】:How do I keep the index of the duplicate element unchanged如何保持重复元素的索引不变
【发布时间】:2012-07-15 08:01:30
【问题描述】:

这是一个输入列表:

['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']]

我怎样才能得到预期的结果?

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

【问题讨论】:

  • 多谢了,这个关键点我忘了

标签: python map indexing enumerate


【解决方案1】:
>>> 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']]

【讨论】:

  • @IgorChubin 取决于 OP 想要什么,他没有未排序列表的结果,所以我不确定......
  • 没错。但是当您需要未排序列表的解决方案并想要保存其顺序时,这根本不起作用。
【解决方案2】:
[
    [i, x]
    for i, (value, group) in enumerate(itertools.groupby(['a', 'b', 'b', 'c', 'c', 'd']))
    for x in group
]

【讨论】:

  • 与 jamylak 的解决方案相同;仅适用于存储列表。
  • 真的完全一样,只是名称不同,并且与 OP 中的值一致。并且发现速度有点慢:)
【解决方案3】:

听起来您想根据字典顺序对术语进行排名。

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 ]

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

如果如您的修正案所建议的那样,您希望根据首次出现的顺序对项目进行编号,则可以采用不同的方法。以下是简短而甜蜜的,尽管令人反感:

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

【讨论】:

  • 不错的解决方案,但对于长列表来说工作量太大; O(n*log(n)),但显而易见的解决方案需要 O(n)
  • @IgorChubin:你只能通过假设排序输入做得更好。我故意避免这样做。
  • 不需要排序输入。 O(n) 解决方案很明显,您根本需要排序输入。
  • @IgorChubin:您的解决方案不是 O(n)。表达式if k not in d 是 O(log(n)),您可以从 O(n) 循环内部调用它。对未排序的输入进行排序等价于排序,一般情况下没有 O(n) 解。
  • 不,k not in d 它是 O(1)。例如,请参阅stackoverflow.com/questions/1963507/…
【解决方案4】:

当列表被排序时,使用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)) 额外的时间。

【讨论】:

    猜你喜欢
    • 2013-03-21
    • 2016-11-01
    • 1970-01-01
    • 2022-01-18
    • 1970-01-01
    • 2020-10-02
    • 1970-01-01
    • 2020-03-16
    • 2016-12-29
    相关资源
    最近更新 更多