如何在python中使用list [list.index('')]查询

时间:2013-06-15 15:52:23

标签: python list indexing

我在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的位置。纠正我如果我错了。

3 个答案:

答案 0 :(得分:12)

分配列表表达式在分配时从左到右进行评估。

以下是发生的事情:

  • 评估右手表达式以产生(4, 2)
  • 评估
  • a[a.index(2)]以指定4a[2]已更改,列表变为[1, 4, 3, 4, 5, 6, 7]
  • 评估
  • a[a.index(4)]以分配2a[2]再次更改 ,因为现在是4的第一个位置返回{ {1}}。

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

[1, 2, 3, 4, 5, 6, 7]

通过指令索引59,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 (63-72),然后a.index(2)存储STORE_SUBSCR,只评估然后 4 (说明79-85)。

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

.index()

答案 1 :(得分:5)

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本身之外的内容中。像这样单独保存索引可以避免你遇到的竞争条件。

答案 2 :(得分:1)

为避免这种情况,您可以将.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]

这样,当一次足够时,你也可以避免三次调用该方法。