import random def randlist(size): lst = [] for i in range(size): lst.append(random.randint(0, 100)) return lst
リスト内包表記を使った解答:
import random def randlist(size): return [random.randint(0, 100) for i in range(size)]
ramdom(en, ja) モジュールの randint 関数を使うとランダムな整数を得ることが出来ます。
random.randint(a, b)
とすれば、a <= N <= b であるようなランダムな整数 N が返されます。
>>> import random >>> for i in range(30): ... print random.randint(0, 10), ... 5 3 8 8 5 3 6 2 3 10 7 6 6 8 0 0 0 5 1 1 9 9 8 6 4 10 2 0 2 5
import random def randlist(size, lower=0, upper=100): lst = [] for i in range(size): lst.append(random.randint(lower, upper)) return lst
リスト内包表記を使った解答:
import random def randlist(size, lower=0, upper=100): return [random.randint(lower, upper) for i in range(size)]
def qsort(fn, lst): if lst == []: return lst else: def partition(x, lst): a, b = [], [] for i in lst: if fn(i, x): a.append(i) else: b.append(i) return a, b xs, ys = partition(lst[0], lst[1:]) return qsort(fn, xs) + [lst[0]] + qsort(fn, ys) def slencmp(x, y): return len(x) < len(y)
補足:リストにも sort メソッドがあります。
>>> lst = ["short", "double", "int", "long"] >>> lst.sort() >>> lst ['double', 'int', 'long', 'short']
sort メソッドには比較関数を渡す事が出来ます。
>>> help(list) | | sort(...) | L.sort(cmpfunc=None) -- stable sort *IN PLACE*; cmpfunc(x, y) -> -1, 0, 1 |
文字列の長さで比較する lencmp 関数を以下のように作ります。
def lencmp(x, y): a, b = len(x), len(y) if a == b: return 0 elif a < b: return -1 else: return 1
lencmp を sort メソッドに渡すと、文字列の長さで比較が行われるようになります。
>>> lst = ["short", "double", "int", "long"] >>> lst.sort(lencmp) >>> lst ['int', 'long', 'short', 'double']
コマンドラインで指定されたファイルを読み込み、改行でスプリットします。左側に表示されるファイルに対して、ファイルの各行のうち最も長い行の長さを width に代入します。この width の値を引数にして各行の文字列に対し ljust メソッドを呼び出して、各行の長さが等しくなるようにしています。
def par(filename1, filename2): file1 = open(filename1) file2 = open(filename2) ls = file1.read().split("\n") width = max(map(len, ls)) ls = [s.ljust(width) for s in ls] output(ls, width, file2.read().split("\n")) file1.close() file2.close() def output(lls, lwidth, rls): llen, rlen = len(lls), len(rls) s = " " * lwidth for i in range(max(llen, rlen)): if i < llen: print lls[i], if i < rlen: print "| %s" % rls[i] else: print "|" else: print "%s | %s" % (s, rls[i]) if __name__ == "__main__": import sys if len(sys.argv) != 3: print "usage: python par.py file1 file2" else: par(sys.argv[1], sys.argv[2])
import sys, glob if len(sys.argv) != 3: print "usage: python rename.py ext new_ext" else: ext, new_ext = sys.argv[1], sys.argv[2] length = len(ext) for filename in glob.glob("*" + ext): new_filename = filename[:-length] + new_ext print filename, "=>", new_filename
glob(en, ja) モジュールの glob 関数にファイル名のパターンを指定すると、それにマッチするファイルのリストが返されます。
>>> import glob >>> glob.glob("*") ['sugar.txt', 'salt.txt', 'pepper.txt', 'prog.py', 'foo.py', 'rename.py', 'main.c'] >>> glob.glob("*.txt") ['sugar.txt', 'salt.txt', 'pepper.txt'] >>> glob.glob("*.c") ['main.c']
glob 関数で指定された拡張子のファイルのリストを得ます。それからファイル名の拡張子部分を取り去り、指定された新しい拡張子をそれに連結しています。
また、実際にファイル名の変更を行うには、os(en, ja) モジュールの rename 関数を使います。
補足:glob のほかに文字列メソッドの endswith を使うのもいいかもしれません。
>>> print str.endswith.__doc__ S.endswith(suffix[, start[, end]]) -> bool Return True if S ends with the specified suffix, False otherwise. With optional start, test S beginning at that position. With optional end, stop comparing S at that position. >>> ls = ["sugar.txt", "salt.txt", "pepper.c"] >>> [x for x in ls if x.endswith(".txt")] ['sugar.txt', 'salt.txt'] >>> [x for x in ls if x.endswith(".c")] ['pepper.c']
def mapconcat(fn, seq, sep): return sep.join(map(fn, seq))
文字列メソッドに join があります。join メソッドは、
s.join(sequence)
とあるとき、引数の sequence をつなげた文字列を返します。そのとき、各要素のセパレータは s となります。
>>> "-".join(["foo", "bar", "baz"]) 'foo-bar-baz'
map 関数は引数として 1 つの関数と 1 つ以上のシーケンスを受け取ります。この関数はシーケンスの各要素に関数を適用した結果のリストを返します。
>>> map(lambda x: x+10, [1, 2, 3]) [11, 12, 13] >>> map(lambda x,y: x+y, [1, 2, 3], [4, 5, 6]) [5, 6, 7]
なお、上の mapconcat 関数では map の代わりにリスト内容表記を使うことも出来ます。
def mapconcat(fn, seq, sep): return sep.join([fn(e) for e in seq])
※mapconcat は、Emacs Lisp の mapconcat 関数を参考にしました。
問題1
def myfilter(fn, ls): ret = [] for e in ls: if fn(e): ret.append(e) return ret # リスト内包表記を使った例 def myfilter(fn, ls): return [e for e in ls if fn(e)]
問題2
def partition(fn, ls): a, b = [], [] for e in ls: if fn(e): a.append(e) else: b.append(e) return a, b
問題3
>>> ls = [("Beth", 43), ("Kathy", 80), ("Mark", 56), ("Mary", 70), ("Susie", 68)] >>> partition(lambda x: x[1] >= 60, ls) ([('Kathy', 80), ('Mary', 70), ('Susie', 68)], [('Beth', 43), ('Mark', 56)])
def flatten(ls): def rec(xs, r): for e in xs: if type(e) is list: rec(e, r) else: r.append(e) return r return rec(ls, [])
あるいは
def flatten(ls): r = [] for e in ls: if type(e) is list: r.extend(flatten(e)) else: r.append(e) return r
def grange(a, b=None, step=1): if b is None: cur = 0 stop = a else: cur = a stop = b assert step != 0 if step > 0: while cur < stop: yield cur cur += step else: while cur > stop: yield cur cur += step