【问题标题】:Iterating through tuples in a list遍历列表中的元组
【发布时间】:2018-09-13 21:10:56
【问题描述】:

假设我有一个由元组组成的列表:

 stList = [('NJ', 'Burlington County', '12/21/2017'),
 ('NJ', 'Burlington County', '12/21/2017'),
 ('NJ', 'Burlington County', '12/21/2017'),
 ('VA', 'Frederick County', '2/13/2018'),
 ('MD', 'Montgomery County', '8/7/2017'),
 ('NJ', 'Burlington County', '12/21/2017'),
 ('NC', 'Lee County', '1/14/2018'),
 ('NC', 'Alamance County', '11/28/2017'),]

我想遍历每个项目(元组),如果它已经存在,请将其从stList 中删除。

for item in stList:
    if item in stList:
        stList.remove(item)

这并不完全有效。基本上,当我运行这个时,如果元组中的 any 项目也在列表中,它会删除该项目,所以我得到这个:

[('NJ', 'Burlington County', '12/21/2017'),
 ('VA', 'Frederick County', '2/13/2018'),
 ('NJ', 'Burlington County', '12/21/2017'),
 ('NC', 'Alamance County', '11/28/2017')]

有什么更好的方法来解决这个问题?

【问题讨论】:

    标签: list tuples comparison python-3.6


    【解决方案1】:

    您可以直接比较元组。

    所有条目匹配的元组将被视为相等。

    >>> ('NJ', 'Burlington County', '12/21/2017') == ('NJ', 'Burlington County', '12/21/2017')
    >>> True
    
    >>> ('NJ', 'Burlington County', '12/21/2017') == ('NJ', 'Burlington County', '1/21/2017')
    >>> False
    

    不要从您正在迭代的集合中删除项目。

    这可能会导致意外行为,除非您知道删除是如何完成的并且您正在正确执行。那是另一回事。

    这里有几个选项。

    seen = set()
    result = []
    for item in stList:
        # Tuple can be compared directly to other tupled in `seen`.
        if item not in seen:
            seen.add(item)
            result.append(item)
    
    stList = result
    

    另一种可能是

    seen = set()
    # Use a list to preserve ordering. Change to set if that does not matter.
    first_seen = []
    for i, item in enumerate(stList):
        if item not in seen:
            seen.add(item)
            first_seen.append(i)
    
    stList = [stList[i] for i in first_seen]
    

    编辑 第二个想法第二个选项不如第一个选项好,除非您出于某种原因需要索引(即,它们可以被重用于其他任务)因为result在第一种情况下存储引用而不是元组的副本所以它将产生或多或少与在stList 中存储这些元组的索引相同的内存。

    如果订购无关紧要

    stList = list(set(stList))
    

    如果您只想要一个可迭代对象并且不需要索引stList,那么您甚至可以将其保留为set 对象。

    【讨论】:

    • 这很好用。我现在同意尝试从我正在迭代的列表中删除项目是一个坏主意。因此,seen 只是比较的临时保留点。非常好;谢谢!
    • @gwydion93 是的。 seen 是一个 set,用于跟踪迄今为止遇到的项目。如果您对数据结构有更多的知识/控制,通常可以改进此步骤,例如,通过在位级别工作或制作您自己的自定义哈希函数等。如果问题不受约束且没有任何特定结构,通常它很难在此处删除 seen 之类的变量。
    猜你喜欢
    • 1970-01-01
    • 2019-03-17
    • 2019-11-16
    • 2013-04-07
    • 1970-01-01
    • 1970-01-01
    • 2017-11-02
    • 1970-01-01
    相关资源
    最近更新 更多