2017-12-27 333 views
3

我只是在玩python以更深入地理解事物。列表名单的移调

我了解到,其中一个更简单的方法是使用zip,但这个怎么样:

>>> a = [[1,1,1], [2,2,2], [3,3,3]] 
>>> for i in range(len(a)): 
... for j in range(len(a[0])): 
...  a[i][j], a[j][i] = a[j][i], a[i][j] 
... 
>>> a 
[[1, 1, 1], [2, 2, 2], [3, 3, 3]] 
>>> 

很好,我期待的回答是

[[1, 2, 3], [1, 2, 3], [1, 2, 3]] 

,因为这是移调将会 ?我调换了元素,对吧? 另外,这种方式对我来说更自然。我阅读了zip here的文档,并没有提到任何有关这种“技巧”的内容。如何学习这些更pythonic的方式做事情?我知道要求学习资源进入主观选择,所以SO不鼓励这样的问题。但国际海事组织在这种情况下显然不是一个选择问题,而是在可获得这些信息的任何资源中找到。

+3

我不明白这一点。这里有问题吗? –

+0

您是否注意到您的清单并未最终转换? – user2357112

+0

@cᴏʟᴅsᴘᴇᴇᴅ,编辑问题 – Adorn

回答

11

你换l[0][1]l[1][0] ...然后当你到l[1][0],你换l[1][0]l[0][1]。除了对角元素外,每对元素都会被交换两次,但是无论如何,这些元素都会与自己交换。一切都回到它开始的地方。

如果要执行由要素互换转置,则需要避免交换对两次:

for i in range(len(a)): 
    for j in range(i+1, len(a)): 
     a[i][j], a[j][i] = a[j][i], a[i][j] 

而且,你转隐含地假定方输入。如果您获得3x5输入,则不能将a[2][4]a[4][2]对换,因为没有a[4][2]

+0

很棒,你添加了关于矩形的免责声明矩阵。 –

+0

错过!对问题的第二部分有何评论?在哪里学习更多pythonic方法来做事情,比如使用'zip'进行转置?我的自然思维过程是迭代,然后交换。 'zip'文档没有涉及它,因此我称之为“诡计” – Adorn

+0

@Adorn:[Google做了一个体面的工作](https://www.google.com/search?q=python+transpose),尽管你不应该自动信任Google提供的任何内容。 – user2357112

0

问题在于你在循环中覆盖了a,这样在第一次转置操作之后,第二个操作只是撤消了第一个转置操作。

您可以复制a(而不是覆盖a),或者通过列表理解来完成。

import copy 
a = [[1,1,1], [2,2,2], [3,3,3]] 
a2 = copy.deepcopy(a) 
for i in range(len(a)): 
    for j in range(len(a[0])): 
    a2[i][j] = a[j][i] 

a3 = [[a[j][i] for j, _ in enumerate(ai)] for i, ai in enumerate(a)] 

print(a) 
print(a2) 
print(a3) 
1

你也可以只使用一个基本的列表理解这里:

a = [[1,1,1], [2,2,2], [3,3,3]] 

transposed = [[x[i] for x in a] for i in range(len(a[0]))] 

print(transposed) 
# [[1, 2, 3], [1, 2, 3], [1, 2, 3]]