「Python」の版間の差分

提供: Wikinote
移動: 案内検索
(リストを最大 N 個に分割する)
(バージョンによる違い)
 
(同じ利用者による、間の27版が非表示)
行8: 行8:
 
* グローバル変数など、外側のスコープにある変数は読み出し専用となる。<code>global</code> 文を使えば代入できる。
 
* グローバル変数など、外側のスコープにある変数は読み出し専用となる。<code>global</code> 文を使えば代入できる。
 
* 一定時間待ちを入れる場合は、<code>import time</code> して <code>time.sleep(n)</code> を使う。
 
* 一定時間待ちを入れる場合は、<code>import time</code> して <code>time.sleep(n)</code> を使う。
 +
* gzip コマンドで圧縮したデータを zlib モジュールでは展開できない (ヘッダが異なるため)。gzip + StringIO モジュールを使って回避する。
 +
* 対話モードでは、最後に表示された結果は変数 <code>_</code> に代入される。
 +
* <code>print</code> の末尾にコンマを入れると、改行されない。<code>print "hoge",</code>
 +
* 一つの要素のタプルは、値の後ろにコンマを付ける。<code>("hoge",)</code>
 +
* 複数の比較演算子を <code>a < b == c</code> のように書ける素晴らしい言語。
 +
* <code>print >> sys.stderr, ...</code> で標準エラーに出力
  
 
== 文字列 ==
 
== 文字列 ==
行31: 行37:
 
  s[-4]  → 'e'
 
  s[-4]  → 'e'
 
  s[-3:] → 'llo' # 末尾 3 文字
 
  s[-3:] → 'llo' # 末尾 3 文字
 +
s[:-1] → 'Hell' # 最後の 1 文字を削る (改行削りに有用)
 
  s[:]  → コピーを作る
 
  s[:]  → コピーを作る
  
行46: 行53:
 
  a = a + [6, 7]  # 連結 → [0, 5, 6, 7]
 
  a = a + [6, 7]  # 連結 → [0, 5, 6, 7]
 
  a = a * 2      # 連続 → [0, 5, 6, 7, 0, 5, 6, 7]
 
  a = a * 2      # 連続 → [0, 5, 6, 7, 0, 5, 6, 7]
 +
 +
* [http://www.python.jp/doc/2.5/tut/node7.html 5. データ構造]
 +
 +
== バージョンによる違い ==
 +
 +
{| class="wikitable" style="text-align: center"
 +
! !! RHEL5 !! RHEL6 !! RHEL7
 +
|-
 +
! Python
 +
| 2.4.3 || 2.6.6 || 2.7.5
 +
|-
 +
! [http://docs.python.jp/2/reference/compound_stmts.html#the-with-statement with 文]
 +
| x || o || o
 +
|-
 +
! [http://docs.python.jp/2/reference/expressions.html#conditional-expressions 条件演算]<br />(三項演算子)
 +
| x || o || o
 +
|-
 +
! リスト内包表記
 +
| o || o || o
 +
|-
 +
! 辞書内包表記
 +
| x || x || o
 +
|-
 +
! [http://docs.python.jp/2/reference/expressions.html#generator-expressions ジェネレータ式]
 +
| o || o || o
 +
|-
 +
! [http://docs.python.jp/2/library/functions.html#enumerate enumerate 関数]<br />の start 引数
 +
| x || o || o
 +
|-
 +
! [http://docs.python.jp/2/reference/compound_stmts.html#the-try-statement try... except... finally]
 +
| x || o || o
 +
|-
 +
! sort/[http://docs.python.jp/2/library/functions.html#sorted sorted] の key 引数
 +
| o || o || o
 +
|-
 +
! [http://docs.python.jp/2/library/functions.html#property @property デコレータ]
 +
| o || o || o
 +
|-
 +
! property オブジェクトの<br>getter, setter, deleter 関数
 +
| x || o || o
 +
|-
 +
! [http://docs.python.jp/2/library/functions.html#all all, any 関数]
 +
| x || o || o
 +
|-
 +
! [http://docs.python.jp/2/library/functions.html#bin bin 関数]
 +
| x || x || o
 +
|}
 +
 +
※RHEL4 は 2.3.4、RHEL3 は 2.2.3。
  
 
== その他 ==
 
== その他 ==
行57: 行113:
 
     return [ list[i:i+size] for i in range(0, l, size) ]
 
     return [ list[i:i+size] for i in range(0, l, size) ]
  
=== getopt テンプレート ===
+
こんな感じで分割したリストのリストになる。
 +
 
 +
>>> l = [1,2,3,4,5,7,8,9,10]
 +
>>> split_list(l, 2)
 +
[[1, 2, 3, 4, 5], [7, 8, 9, 10]]
 +
>>> split_list(l, 3)
 +
[[1, 2, 3], [4, 5, 7], [8, 9, 10]]
 +
>>> split_list(l, 4)
 +
[[1, 2, 3], [4, 5, 7], [8, 9, 10]]
 +
>>> split_list(l, 5)
 +
[[1, 2], [3, 4], [5, 7], [8, 9], [10]]
 +
 
 +
=== モジュールに定義された名前のリスト ===
 +
 
 +
dir 関数を使う。(忘れやすい)
 +
 
 +
>>> dir()
 +
['__builtins__', '__doc__', '__name__', '__package__']
 +
>>> import time
 +
>>> dir()
 +
['__builtins__', '__doc__', '__name__', '__package__', 'time']
 +
>>> dir(time)
 +
['__doc__', '__file__', '__name__', '__package__', 'accept2dyear', 'altzone', 'asctime', 'clock',
 +
'ctime', 'daylight', 'gmtime', 'localtime', 'mktime', 'sleep', 'strftime', 'strptime',
 +
'struct_time', 'time', 'timezone', 'tzname', 'tzset']
 +
 
 +
=== socket の setsockopt() を使う ===
 +
 
 +
* SO_KEEPALIVE の場合
 +
 
 +
import socket
 +
s = socket.socket()
 +
s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
 +
 
 +
* SO_LINGER の場合
 +
 
 +
import socket
 +
import struct
 +
s = socket.socket()
 +
s.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 30))
 +
 
 +
== テンプレート ==
 +
 
 +
=== awk 風 Python スクリプトテンプレート ===
 +
 
 +
テキスト処理を何でもかんでも簡単な awk で済ませちゃうクセがついてしまったので、
 +
自分に Python を使うように仕向けるための awk 風テンプレート。
 +
 
 +
FS, NR, FILENAME, FNR, NF, s[0], s[1..NF] が利用可能。
 +
 
 +
#!/usr/bin/env python
 +
import sys
 +
 +
if len(sys.argv) == 1:
 +
    files = [ sys.stdin ]
 +
else:
 +
    files = [ open(f) for f in sys.argv[1:] ]
 +
 +
### BEGIN {
 +
FS = None
 +
 +
### }
 +
 +
NR = 0
 +
for file in files:
 +
    FNR = 0; FILENAME = file.name
 +
    for line in file:
 +
        NR += 1; FNR += 1
 +
        s = line.split(FS)
 +
        s[0:0] = [ line[:-1] ]
 +
        NF = len(s)
 +
        # print NR, FILENAME, FNR, NF, s
 +
        ### {
 +
 +
        ### }
 +
 +
### END {
 +
 +
### }
 +
 
 +
=== ファイルか標準入力から読む ===
 +
 
 +
ファイルが指定されれば、それらをすべて処理し、指定されなければ標準入力から読む。
 +
 
 +
import sys
 +
 +
if len(sys.argv) == 1:
 +
    files = [ sys.stdin ]
 +
else:
 +
    files = [ open(f) for f in sys.argv[1:] ]
 +
 +
for file in files:
 +
    ...
 +
 
 +
* [http://docs.python.jp/2/library/fileinput.html fileinput モジュール] というのがあった…
 +
 
 +
=== getopt ===
 
どの言語でもこいつだけはテンプレート化する必要がある。。
 
どの言語でもこいつだけはテンプレート化する必要がある。。
  
ソースコード <toggledisplay>
+
  import sys
  import sys, getopt
+
import getopt
  def usage():
+
     print "Usage: %s [-a] [-b str]" % sys.argv[0]
+
  def usage(exit_code):
     sys.exit(0)
+
    out = (exit_code and sys.stderr) or sys.stdout
 +
     print >> out, 'Usage: %s [-a] [-b str]' % sys.argv[0]
 +
     sys.exit(exit_code)
 
   
 
   
 
  try:
 
  try:
     opts, args = getopt.getopt(sys.argv[1:], "ab:")
+
     opts, args = getopt.getopt(sys.argv[1:], 'ab:h')
 
  except getopt.GetoptError:
 
  except getopt.GetoptError:
     usage()
+
     usage(1)
 
   
 
   
 
  (opt_a, opt_b) = (False, None) # defaults
 
  (opt_a, opt_b) = (False, None) # defaults
 
  for (opt, val) in opts:
 
  for (opt, val) in opts:
     if opt == "-a":
+
     if opt == '-a':
 
         opt_a = True
 
         opt_a = True
     elif opt == "-b":
+
     elif opt == '-b':
 
         opt_b = val
 
         opt_b = val
 +
    elif opt == '-h':
 +
          usage(0)
 +
    else:
 +
          usage(1)
 
   
 
   
 
  for arg in args: # remainder
 
  for arg in args: # remainder
 
     ...
 
     ...
</toggledisplay>
 

2017年10月24日 (火) 23:54時点における最新版

かなり忘れつつある Python について。

参考リンク

覚え書き

  • グローバル変数など、外側のスコープにある変数は読み出し専用となる。global 文を使えば代入できる。
  • 一定時間待ちを入れる場合は、import time して time.sleep(n) を使う。
  • gzip コマンドで圧縮したデータを zlib モジュールでは展開できない (ヘッダが異なるため)。gzip + StringIO モジュールを使って回避する。
  • 対話モードでは、最後に表示された結果は変数 _ に代入される。
  • print の末尾にコンマを入れると、改行されない。print "hoge",
  • 一つの要素のタプルは、値の後ろにコンマを付ける。("hoge",)
  • 複数の比較演算子を a < b == c のように書ける素晴らしい言語。
  • print >> sys.stderr, ... で標準エラーに出力

文字列

  • シングルクォートとダブルクオートに違いはない。
    • エスケープシーケンスを無視する場合は raw 文字列を使う。r"raw 文字列\n"
  • 三重クォート """ あるいは ''' は改行をそのまま含めることができる。
  • 連結は + 演算子を用いる。
    • 文字列リテラルは、列記で連結可能。"ho" "ge" → "hoge"
  • len() 組み込み関数でバイト数を得る。
    • マルチバイトを考慮した文字数は len(str.decode("UTF-8")) で得ることができる。
  • in で包含判定ができる
  • int(str) で整数に変換。第 2 引き数で基数指定可能。

スライス

文字の間に添字を置くとわかりやすい。

s = "H e l l o"
    0 1 2 3 4 5
  - 5 4 3 2 1   ← ここは -0 でないことに注意!! (0 = -0 のため)

s[1]   → 'e'
s[:3]  → 'Hel' # 先頭 3 文字
s[3:]  → 'lo'
s[-4]  → 'e'
s[-3:] → 'llo' # 末尾 3 文字
s[:-1] → 'Hell' # 最後の 1 文字を削る (改行削りに有用)
s[:]   → コピーを作る

リスト

書くのが面倒なくらい柔軟性に富んだデータ型である。

  • 変更可能 (mutable)
  • 入れ子可能 (リストの要素をリストにできる)
  • 文字列と同様のスライス表現で操作できる。
  • len() でリストの長さを得る。
a = []          # 初期化、クリア
a = [0, 3, 5]
a[1:1] = [1, 2] # 挿入 → [0, 1, 2, 3, 5]
a[1:4] = []     # 削除 → [0, 5]
a = a + [6, 7]  # 連結 → [0, 5, 6, 7]
a = a * 2       # 連続 → [0, 5, 6, 7, 0, 5, 6, 7]

バージョンによる違い

RHEL5 RHEL6 RHEL7
Python 2.4.3 2.6.6 2.7.5
with 文 x o o
条件演算
(三項演算子)
x o o
リスト内包表記 o o o
辞書内包表記 x x o
ジェネレータ式 o o o
enumerate 関数
の start 引数
x o o
try... except... finally x o o
sort/sorted の key 引数 o o o
@property デコレータ o o o
property オブジェクトの
getter, setter, deleter 関数
x o o
all, any 関数 x o o
bin 関数 x x o

※RHEL4 は 2.3.4、RHEL3 は 2.2.3。

その他

リストを N 分割する

ちょうど N 個に分割するわけではなく、最大で N 個なので注意。

def split_list(list, n):
    l = len(list)
    size = l / n + (l % n > 0)
    return [ list[i:i+size] for i in range(0, l, size) ]

こんな感じで分割したリストのリストになる。

>>> l = [1,2,3,4,5,7,8,9,10]
>>> split_list(l, 2)
[[1, 2, 3, 4, 5], [7, 8, 9, 10]]
>>> split_list(l, 3)
[[1, 2, 3], [4, 5, 7], [8, 9, 10]]
>>> split_list(l, 4)
[[1, 2, 3], [4, 5, 7], [8, 9, 10]]
>>> split_list(l, 5)
[[1, 2], [3, 4], [5, 7], [8, 9], [10]]

モジュールに定義された名前のリスト

dir 関数を使う。(忘れやすい)

>>> dir()
['__builtins__', '__doc__', '__name__', '__package__']
>>> import time
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'time']
>>> dir(time)
['__doc__', '__file__', '__name__', '__package__', 'accept2dyear', 'altzone', 'asctime', 'clock',
'ctime', 'daylight', 'gmtime', 'localtime', 'mktime', 'sleep', 'strftime', 'strptime',
'struct_time', 'time', 'timezone', 'tzname', 'tzset']

socket の setsockopt() を使う

  • SO_KEEPALIVE の場合
import socket
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
  • SO_LINGER の場合
import socket
import struct
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 30))

テンプレート

awk 風 Python スクリプトテンプレート

テキスト処理を何でもかんでも簡単な awk で済ませちゃうクセがついてしまったので、 自分に Python を使うように仕向けるための awk 風テンプレート。

FS, NR, FILENAME, FNR, NF, s[0], s[1..NF] が利用可能。

#!/usr/bin/env python
import sys

if len(sys.argv) == 1:
    files = [ sys.stdin ]
else:
    files = [ open(f) for f in sys.argv[1:] ]

### BEGIN {
FS = None

### }

NR = 0
for file in files:
    FNR = 0; FILENAME = file.name
    for line in file:
        NR += 1; FNR += 1
        s = line.split(FS)
        s[0:0] = [ line[:-1] ]
        NF = len(s)
        # print NR, FILENAME, FNR, NF, s
        ### {

        ### }

### END {

### }

ファイルか標準入力から読む

ファイルが指定されれば、それらをすべて処理し、指定されなければ標準入力から読む。

import sys

if len(sys.argv) == 1:
    files = [ sys.stdin ]
else:
    files = [ open(f) for f in sys.argv[1:] ]

for file in files:
    ...

getopt

どの言語でもこいつだけはテンプレート化する必要がある。。

import sys
import getopt

def usage(exit_code):
    out = (exit_code and sys.stderr) or sys.stdout
    print >> out, 'Usage: %s [-a] [-b str]' % sys.argv[0]
    sys.exit(exit_code)

try:
    opts, args = getopt.getopt(sys.argv[1:], 'ab:h')
except getopt.GetoptError:
    usage(1)

(opt_a, opt_b) = (False, None) # defaults
for (opt, val) in opts:
    if opt == '-a':
        opt_a = True
    elif opt == '-b':
        opt_b = val
    elif opt == '-h':
         usage(0)
    else:
         usage(1)

for arg in args: # remainder
    ...