7
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Python初心者メモ(その2)

Last updated at Posted at 2016-07-15

Pythonでもっと遊んでもう少し学んだので、前回の続きとして書きます。

関係ないですけど、Python使いのことはPythonistaって言うんですね。
めざせPythonista!!

配列系

要素アクセス

普通の

items = ["A", "B", "C", "D", "E"]
item = items[1] # インデックス1の要素を取得
print(item) # B

最近学んだ

items = ["A", "B", "C", "D", "E"]
item = items[-1] # 最後のの要素を取得
# item = items[len(items) - 1] # こんなことしなくてもいい
print(item) # E

-2を指定したら後ろから2番目"D"が取れる

配列コピー

前回も書いたけどこんな感じ。

items = ["A", "B", "C", "D", "E"]
items2 = items[1:3] # index 1から2を抽出したlist生成
print(items2) # ['B', 'C']

items3 = items[1:] # index 1から後ろ全部を抽出したlist生成
print(items3) # ['B', 'C', 'D', 'E']

items4 = items[:3] # index 3からより前全部を抽出したlist生成
print(items4) # ['A', 'B', 'C']

さらに、飛び飛びでとることもできる。

items = ["A", "B", "C", "D", "E", "F", "G"]
items6 = items[::2] # 1つ飛ばしで抽出したlist生成
print(items6) # ['A', 'C', 'E', 'G']

items7 = items[::-1] # 逆順のlist生成
print(items7) # ['G', 'F', 'E', 'D', 'C', 'B', 'A']

items8 = items[-1:3:-1] # 逆順でindex範囲を指定するなら開始を後ろにする。(逆にすると要素が取れない)
print(items8) # ['G', 'F', 'E']

for文

当然だが[::]を使って配列のループが色々できる

items = ["A", "B", "C", "D", "E", "F", "G"]
for item in items[1:]:
    print(item) # B,C,D,E,F,Gを順番にprint

print("---")

for item in items[::-1]:
    print(item) # G,F,E,D,C,B,Aを順番にprint

print("---")

for item in items[::3]:
    print(item) # A,D,Gを順番にprint

for文でindexもとる

やり方があった。

items = ["A", "B", "C", "D", "E"]

for i, value in enumerate(items):
    print(str(i) + ":"+ value)

結果

0:A
1:B
2:C
3:D
4:E

リストの内包表記

(for文とは別物かも)
http://docs.python.jp/3.5/tutorial/datastructures.html#list-comprehensions

配列の中身を操作して別の配列を作りたいとき

items = ["a", "B", "c", "D", "e"]

# 大文字にしたlistを作る
items2 = []
for item in items:
    items2.append(item.upper())

print(items2) # ['A', 'B', 'C', 'D', 'E']

て書きそうなところ、items2を作るループの処理は、下記のように書ける。

items2 = [item.upper() for item in items]

ちなみにmapを利用すると、下記のように書ける。

items2 = list(map(str.upper, items))

さらに、

items = ["a", "B", "c", "D", "e"]

# 大文字だけのlistを作る
items2 = []
for item in items:
    if item.upper() == item:
        items2.append(item)

print(items2) # ['B', 'D']

て書きそうなところ、items2を作るループの処理は、下記のように書ける。

items2 = [item for item in items if item.upper() == item]

結合

個人的に結構感動するPythonの配列結合
なんと+演算子だけでできた。

item1 = ["A", "B", "C"]
item2 = ["D", "E"]

item3 = item1 + item2
print(item3) # ['A', 'B', 'C', 'D', 'E']

(extendと違って別のlistが作られる)

予想できるが当然、加算代入も可能

item1 = ["A", "B", "C"]
item2 = ["D", "E"]

item1 += item2
# item1.extend(item2)と結果は同じ
print(item1) # ['A', 'B', 'C', 'D', 'E']

そして個人的に全く理解できないのがある。

item1 = ["A", "B", "C"]
item2 = ["D", "E"]

item1[:0] = item2
print(item1) # ['D', 'E', 'A', 'B', 'C']

上記のように書くと頭に結合できる。

慣れない僕はさすがに理解できないので当分は、

item1 = item2 + item1

と書くと思う。

文字列操作

join

前回書いておくべきだった内容かも)

s = ":".join(["A", "B", "C", "D", "E"])

print(s) # "A:B:C:D:E"

繰り返し

これも個人的に結構感動してる方法。
なんと*演算子だけでできた。(これ知るまでループ書いてた)

s = "" * 5
print(s) # あああああ

lambda式

こう書く。lambda式の書き方自体は、今となってはJavaとあまり変わらない。

func = lambda x: x.upper()

print(func("a")) # A

条件文

in

配列に含まれるかどうかを判定(したり)する。(dictだとまた動作が違う)
orで繋がなくていい便利なやつ。

http://docs.python.jp/3.5/reference/expressions.html#membership-test-operations
帰属検査演算という名前らしい。
SQLのINみたいな?神殿マークの言語でもできたなぁという個人的思い出。

if 2 in [1, 2, 3]: # True
    print("2がある")

if 4 not in [1, 2, 3]: # True
    print("4はない")

yield

http://docs.python.jp/3.5/reference/expressions.html#yieldexpr
http://docs.python.jp/3.5/reference/simple_stmts.html#the-yield-statement

yieldが何なのかの説明はできないので下記を参考
https://ja.wikipedia.org/wiki/ジェネレータ_(プログラミング)

JavaでいうIteratorを、簡単に作る仕組みと勝手に理解した。

def yield_sample():
    for i in [1, 2, 3]:
        yield i

gen = yield_sample()

print(next(gen))  # 1
print(next(gen))  # 2
print(next(gen))  # 3
print(next(gen))  # StopIteration
for i in yield_sample(): # for文で回せる
    print(i)  # 1、2、3を順番に出力

次がyieldの面白いところ

def yield_sample2():
    print("つぎは1")
    yield 1
    print("つぎは2")
    yield 2
    print("つぎは3")
    yield 3
    print("つぎはない")

for i in yield_sample2():
    print(i)  # 1、2、3を順番に出力するが、、、

結果はこう

つぎは1
1
つぎは2
2
つぎは3
3
つぎはない

yieldで作成したジェネレータをlistにしたい場合はこう

def yield_sample():
    for i in [1, 2, 3]:
        yield i

l = list(yield_sample())
print(l) # [1, 2, 3]

ファイル操作系

ググったほうが早いかも。いくつかやり方がある印象を受けた。
どの方法が最も良いのかまではわからない。
ファイル操作系全部は書かないけど、自分が使ったものだけ書いておく。

読み込み

f = codecs.open(path, "r", "utf-8")
ret = f.read()
f.close()

書き込み

f = codecs.open(path,"w", "utf-8")
f.write(value)
f.close()

ファイル存在

if os.path.exists(path):

フォルダ掘る

os.makedirs(dirPath)

親フォルダ名取得

os.path.dirname(path)

ディレクトリからファイルのリストアップ

for root, _, files in os.walk(dirPath):
    for fileName in files:
        path = os.path.join(root, fileName)
        yield path

例外処理

except

Javaでいうcatchブロック

def error_throw():
    "" + 1

try:
    error_throw()
    print("ここにはこない")
except: # すべてのエラーでここに来る
    print("エラー")

catch的なやつ

try:
    error_throw()
    print("ここにはこない")
except Exception as e: # エラーObjectを取得
    print(type(e))
    print(e)

結果

<class 'TypeError'>
Can't convert 'int' object to str implicitly

Exceptionの型別にもかける

try:
    error_throw()
    print("ここにはこない")
except ValueError:
    print("ValueErrorは発生しないのでここにはこない")
except TypeError:
    print("TypeErrorが発生するのでここにくる")

trace

Javaでいうstacktraceてきなやつ

import traceback

try:
    error_throw()
except :
    print(traceback.format_exc())

クロージャ

できない。ざんねん。Javaと似たイメージでできない。

def new_counter():
    count = 0
    def func():
        count += 1
        return count
    return func

c = new_counter()
print(c())
print(c())
print(c())

エラー

UnboundLocalError: local variable 'count' referenced before assignment

下記のように書けばそれっぽいことができる。。。(Javaみたい)

def new_counter():
    count = [0]
    def func():
        count[0] += 1
        return count[0]
    return func

c = new_counter()
print(c())
print(c())
print(c())

テスト

作成

Eclipseから「新規」→「Pydevモジュール」→名前を付けて「完了」→
「モジュール:Unittest」を選択して「OK」で出来たものをみればなんとなく書き方がわかると思う。

実行

「実行」→「Pythonユニットテスト」で実行できる。

サンプル

import unittest


class Test(unittest.TestCase):


    def testName(self):
        self.assertEqual(1, 2, "サンプル")


if __name__ == "__main__":
    #import sys;sys.argv = ['', 'Test.testName']
    unittest.main()

結果

F
======================================================================
FAIL: testName (__main__.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\hogehoge\testsample.py", line 13, in testName
    self.assertEqual(1, 2, "サンプル")
AssertionError: 1 != 2 : サンプル

----------------------------------------------------------------------
Ran 1 test in 0.016s

FAILED (failures=1)

テストの動的追加

下記を参考にしました。
http://hirokazumiyaji.hatenablog.com/entry/2015/07/16/134238

下記サンプルはディレクトリにあるファイル分のテストを登録するサンプルです。

import unittest
import os


class Test(unittest.TestCase):
    # 空のテストクラス
    pass

def setup_testsuite():
    """
        ディレクトリのファイルをリストアップしてテストを登録
    """
    root = os.getcwd()
    test_files_dir = os.path.join(root, "files") # このpyファイルの隣にあるfilesフォルダの中のファイルをターゲットにする

    def listup():
        for root, _, files in os.walk(test_files_dir):
            for file_name in files:
                if os.path.splitext(file_name)[1].lower() == ".txt":# 拡張子で絞り込み
                    yield file_name, os.path.join(root, file_name)

    for file_name, path in listup():
        def create_test_func(file_name, path):
            def test_func(self):
                """
                    テストの実態
                """
                print("test start: " + file_name)

                # selfはTestなのでassertEqualは下記のように呼ぶ
                # self.assertEqual(first, second, msg)

            return test_func

        test_name = "test_{}".format(file_name)
        setattr(Test, test_name, create_test_func(file_name, path)) #登録

# テストの登録を実行
setup_testsuite()

if __name__ == "__main__":
    # import sys;sys.argv = ['', 'Test.testName']
    unittest.main()
7
9
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?