代码之家  ›  专栏  ›  技术社区  ›  FlyingBurger

python为列表中的每个元素添加id

  •  3
  • FlyingBurger  · 技术社区  · 8 年前

    我想为每个元素添加一个id,如果元素出现多次,应该在第一次出现的时候添加这个id,我不知道这个问题,有人能帮我吗

    输入:

    omg = ['a', 'b', 'c', 'a', 'b', 1]
    

    输出:

    omg_id = [0, 1, 2, 0, 1, 3]
    
    5 回复  |  直到 8 年前
        1
  •  9
  •   user2390182    8 年前

    使用 defaultdict 以下内容:

    from collections import defaultdict
    
    omg = ['a', 'b', 'c', 'a', 'b', 1]
    d = defaultdict(lambda: len(d))  # late binding allows d not to be defined yet
    omg_id = [d[x] for x in omg]
    # [0, 1, 2, 0, 1, 3]
    

    默认工厂为每个新密钥分配当前已知密钥数由于密钥访问不仅返回而且还分配值,因此 拖欠债务 在理解过程中“成长”。

        2
  •  4
  •   jpp    8 年前

    您可以使用带字典的迭代来构造映射然后将此映射应用到原始列表。

    omg = ['a', 'b', 'c', 'a', 'b', 1]
    
    d = {}
    for i in omg:
        if i not in d:
            d[i] = len(d)
    
    omg_id = list(map(d.get, omg))
    
    print(omg_id)
    
    [0, 1, 2, 0, 1, 3]
    

    下面是另一种解决方案,使用 toolz.unique [相当于 unique_everseen 配方在 itertools 文档]:

    from toolz import unique
    
    d = {v: k for k, v in enumerate(unique(omg))}
    omg_id = list(map(d.get, omg))
    

    两种解决方案都具有以下特点:

    • O(n)复杂度。
    • 需要元素 omg 可以散列。
        3
  •  1
  •   whackamadoodle3000    8 年前

    你可以试试这个:

    from more_itertools import unique_everseen
    t=dict([(e,c) for c,e in enumerate(unique_everseen(omg))])
    print([t.get(e) for e in omg])
    
        4
  •  1
  •   Marcus.Aurelianus    8 年前

    Order dict将删除重复项并保留订单您也可以通过以下方法一次性完成:

    from collections import OrderedDict
    
    omg_id=[{v:k for k,v in enumerate(OrderedDict.fromkeys(omg))}[num] for num in omg]
    

    结果:

    [0, 1, 2, 0, 1, 3]
    
        5
  •  0
  •   perreal    8 年前

    使用列表中的项创建一个集合枚举集合并创建具有枚举值键的字典然后使用列表和字典生成所需的输出。

    推荐文章