2017-12-27 881 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]]