【问题标题】:How to use list[list.index('')] queries in python如何在 python 中使用 list[list.index('')] 查询
【发布时间】:2013-06-12 02:24:57
【问题描述】:

我在 python IDLE 中尝试了以下代码。但我似乎没有发现交换的元素。

>>> a = [1,2,3,4,5,6,7]
>>> if(a.index(2)<a.index(4)):
...     a[a.index(2)],a[a.index(4)] = a[a.index(4)],a[a.index(2)]

根据代码,它应该颠倒2和4的位置。如果我错了,请纠正我。

【问题讨论】:

    标签: python list indexing


    【解决方案1】:

    Martijn 的回答很完整,并解释了您遇到的问题。如果您仍然想知道如何编写符合您要求的代码,请尝试以下方法:

    if (a.index(2) < a.index(4)):
        x,y = a.index(4),a.index(2)
        a[x],a[y] = a[y],a[x]
    

    这里的想法基本上只是将 index 返回值存储在 List 本身之外的东西中。像这样单独保存索引可以避免您遇到的竞争条件。

    【讨论】:

    • 这仍然调用.index() 两次太频繁了我的口味:)
    • 我的目标是清晰而不是简洁。 :)
    【解决方案2】:

    赋值列表表达式在赋值时从左到右计算

    会发生什么:

    • 计算右侧表达式以产生 (4, 2)
    • a[a.index(2)] 被评估以将 4 分配给,a[2] 被更改,列表变为 [1, 4, 3, 4, 5, 6, 7]
    • a[a.index(4)] 被评估为将 2 分配给,a[2] 被更改再次,因为现在第一个位置 4 回到了 [1, 2, 3, 4, 5, 6, 7]

    你可以在反汇编的 Python 字节码中看到这一点:

    >>> def foo():
    ...     a = [1,2,3,4,5,6,7]
    ...     a[a.index(2)],a[a.index(4)] = a[a.index(4)],a[a.index(2)]
    ... 
    >>> import dis
    >>> dis.dis(foo)
      2           0 LOAD_CONST               1 (1)
                  3 LOAD_CONST               2 (2)
                  6 LOAD_CONST               3 (3)
                  9 LOAD_CONST               4 (4)
                 12 LOAD_CONST               5 (5)
                 15 LOAD_CONST               6 (6)
                 18 LOAD_CONST               7 (7)
                 21 BUILD_LIST               7
                 24 STORE_FAST               0 (a)
    
      3          27 LOAD_FAST                0 (a)
                 30 LOAD_FAST                0 (a)
                 33 LOAD_ATTR                0 (index)
                 36 LOAD_CONST               4 (4)
                 39 CALL_FUNCTION            1
                 42 BINARY_SUBSCR       
                 43 LOAD_FAST                0 (a)
                 46 LOAD_FAST                0 (a)
                 49 LOAD_ATTR                0 (index)
                 52 LOAD_CONST               2 (2)
                 55 CALL_FUNCTION            1
                 58 BINARY_SUBSCR       
                 59 ROT_TWO             
                 60 LOAD_FAST                0 (a)
                 63 LOAD_FAST                0 (a)
                 66 LOAD_ATTR                0 (index)
                 69 LOAD_CONST               2 (2)
                 72 CALL_FUNCTION            1
                 75 STORE_SUBSCR        
                 76 LOAD_FAST                0 (a)
                 79 LOAD_FAST                0 (a)
                 82 LOAD_ATTR                0 (index)
                 85 LOAD_CONST               4 (4)
                 88 CALL_FUNCTION            1
                 91 STORE_SUBSCR        
                 92 LOAD_CONST               0 (None)
                 95 RETURN_VALUE        
    

    通过指令索引 59,Python 计算了右侧表达式;接下来是作业。您可以看到a.index(2) (63-72) 首先被评估,然后STORE_SUBSCR 存储4,并且只有然后 a.index(4) 被评估(指令79-85)。

    解决方法是为每个值调用.index()一次,并将索引存储在变量中:

    index_two, index_four = a.index(2), a.index(4)
    if index_two < index_four:
        a[index_two], a[index_four] = a[index_four], a[index_two]
    

    【讨论】:

    • 感谢您的回答!那么如果我只能访问它的索引值,我如何交换列表中的 2 和 4?
    【解决方案3】:

    为避免这种情况,您可以将.index() 调用的结果存储在变量中,然后与它们进行交换:

    >>> a = [1,2,3,4,5,6,7]
    >>> i2 = a.index(2)
    >>> i4 = a.index(4)
    >>> if i2<i4:
    ...     a[i2], a[i4] = a[i4], a[i2]
    >>> a
    [1, 4, 3, 2, 5, 6, 7]
    

    这样你也可以避免在一次就足够的情况下调用该方法三次。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-16
      • 2012-11-01
      • 2023-03-16
      • 2014-06-29
      • 1970-01-01
      相关资源
      最近更新 更多