Pythonでメタグループとリストを条件別にソートする方法の例

4618 ワード

pythonでメタグループをソートする
私の同僚のAxel Hechtは私にpythonのソートについて知らないことを示してくれました.pythonでは、メタグループをソートできます.例は最良の説明です.

>>> items = [(1, 'B'), (1, 'A'), (2, 'A'), (0, 'B'), (0, 'a')]
>>> sorted(items)
[(0, 'B'), (0, 'a'), (1, 'A'), (1, 'B'), (2, 'A')]

デフォルトで組み込まれたsort関数とsorted関数が受信するパラメータがメタグループの場合、メタグループの最初の要素でソートし、2番目の要素でソートします.しかしながら、結果(0,'B')は(0,'a')の前にあることに気づいた.これは、大文字BのASCII符号化がaより小さいためである.しかし、より人間的なソートが必要で、大文字と小文字に注目しないと仮定します.あなたはそうするかもしれません.

>>> sorted(items, key=str.lower)
Traceback (most recent call last):
File "", line 1, in 
TypeError: descriptor 'lower' requires a 'str' object but received a 'tuple'

メタグループの最初の部分を正しく処理できないため、エラーが発生します.(注:原文の著者はメタグループの最初の項目は数字で、lowerという方法を使用できないと推定しています.正しい原因は明らかです.あなたが伝えたのはメタグループで、メタグループはlowerという方法がないからです.)
メタグループの要素を1つしか処理していないので、lambda関数(eg.sorted(items,key=lambda x:x.lower()if isinstance(x,str)else x))を書いてみましょう.(注:上と同じように、作者がこのようにするのは必然的に間違っていて、このlambdaにメタグループを伝えることを考えて、帰ってきたのは何ですか?)
本題に戻ると、次はあなたがどうすべきかの方法です.lambdaはメタグループを返します.

>>> sorted(items, key=lambda x: (x[0], x[1].lower()))
[(0, 'a'), (0, 'B'), (1, 'A'), (1, 'B'), (2, 'A')]

今あなたはそれを完成しました!Axelの分かち合いに感謝します!
sorted(items,reverse=True,...)だけを逆順に並べ替えることができることを知っていると確信していますが、キーワードに基づいてどのようにソートしますか?
Lambda関数を使用してメタグループに戻るテクニックです.以下は、少し高度なデータ構造をソートします.

>>> peeps = [{'name': 'Bill', 'salary': 1000}, {'name': 'Bill', 'salary': 500}, {'name': 'Ted', 'salary': 500}]

次に、lambda関数を使用してメタグループのプロパティを返してソートします.

>>> sorted(peeps, key=lambda x: (x['name'], x['salary']))
[{'salary': 500, 'name': 'Bill'}, {'salary': 1000, 'name': 'Bill'}, {'salary': 500, 'name': 'Ted'}]

おもしろいですね.BillはTedの前にあり、500は1000の前にあります.しかし、同じnameでsalaryを逆ソートするにはどうすればいいですか?簡単です.それを逆にします.

>>> sorted(peeps, key=lambda x: (x['name'], -x['salary']))
[{'salary': 1000, 'name': 'Bill'}, {'salary': 500, 'name': 'Bill'}, {'salary': 500, 'name': 'Ted'}]


質問:リスト[[1,2,3],[4,5,6],[7,8,9]]を[[1,4,7],[2,5,8],[3,6,9]]に並べ替えて分析する:
1.転換過程は以下の通りである:
1 2 3          1 4 7 4 5 6   ―> 2 5 8 7 8 9          3 6 9
変換プロセスは、元の2次元配列行(row)が新しい配列になる列(column)と見なすことができ、すなわち、元の配列の第1行(row)を第1列(column)として抽出し、第2行(row)を第2列(column)とすることができる...もちろん、変換プロセスは、元の配列の列が新しい配列になる行と見なすこともでき、時間に限られ、このような実現形態はしばらく考慮されない.2.最も原始的な方法は、2つのforループを書き、外層ループが配列の行(row)、内層ループが配列の列(column)を順次反復して、この反転過程を実現し、元の配列の第1行(row)を第1列(column)、第2行(row)を第2列(column)とし、過程は以下の通りである.

In [7]: l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

In [8]: len_row = 3

In [9]: len_col = 3

In [10]: temp = [[],[],[]]

In [11]: for row in l:
  ....:   for i in range(len_col):
  ....:     temp[i].append(row[i])
  ....:   print temp
  ....:
[[1], [2], [3]]
[[1, 4], [2, 5], [3, 6]]
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]

In [12]:


もちろん、リストの導出も使用できます.原理は上と同じです.外層反復row、内層反復col、新しいリストを生成します.

In [100]: l
Out[100]: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

In [101]: [[row[col] for row in l] for col in range(len(l[0])) ]
Out[101]: [[1, 4, 7], [2, 5, 8], [3, 6, 9]]


最後に、このテーマに対してzipでも同じ目的を達成することができます.

In [104]: l
Out[104]: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

In [105]: zip(*l)
Out[105]: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]

In [106]: map(list,zip(*l))
Out[106]: [[1, 4, 7], [2, 5, 8], [3, 6, 9]]


*この記号とリストには解凍の意味があり、例えばl=[[1,2,3],[4,5,6],[7,8,9]]では、*lが[1,2,3],[4,5,6],[7,8,9]の3つの値になったことを理解しているので、zip(*l)とzip([1,2,3],[4,5,6],[7,8,9])の結果は同じであり、以下のようになる.

In [17]: l=[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

In [18]: zip([1, 2, 3], [4, 5, 6], [7, 8, 9])
Out[18]: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]

In [19]: zip(*l)
Out[19]: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]

In [20]: