python文法の謎

  • pythonにはポインタが存在する?

突然ですが、pythonってポインタが存在するんでしょうか?僕はポインタってC言語でしか見たことがなかったのでpythonでポインタもどきに出会ってしまい、困惑しています。

>>> x, *y = [1, 2, 3]
>>> x
1
>>> y
[2, 3]

これってyがリスト(0~2番)の1番目の場所を指してるポインタってこと?ふーむ*1
他にもこんなことができるのです。

>>> x, *y, z = [1, 2, 3, 4, 5]
>>> x
1
>>> y
[2, 3, 4]
>>> z
5

ほうほう、なるほど。つまりは*がついてる部分の長さは任意なのね。
で、ここからいろんなことを試していく。

>>> *a,*b = [1, 2, 3]
SyntaxError: two starred expressions in assignment
>>> *a,*b = 1, 2, 3
SyntaxError: two starred expressions in assignment

*がついてる部分の長さは任意だから、aとbのポインタがどこからどこまでなのかわかっていないのかな。2つあるともう1つのポインタは迷子になってるのかな?まぁ、なんにせよ無理です。
Learning Python(by Mark Lutz)をひも解いてみると次のように書いてありました。

>>> seq
[1, 2, 3, 4]
Finally, errors can still be triggered if there is more than one starred name, if there are too few values and no star (as before), and if the starred name is not itself coded inside a sequence:
>>> a, *b, c, *d = seq
SyntaxError: two starred expressions in assignment

>>> a, b = seq
ValueError: too many values to unpack

ははぁ・・・、2つ以上のスターは使うなと。で他にも目についた変なこととして

>>> *a,=range(10)
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> *a = [1,2,3,4]
SyntaxError: starred assignment target must be in a list or tuple
>>> a,=[1]
>>> a
1
>>> a,=[1,2,3]
Traceback (most recent call last):
  File "<pyshell#142>", line 1, in <module>
    a,=[1,2,3]
ValueError: too many values to unpack (expected 1)

>>> x,*y,z='abc'
>>> x
'a'
>>> y
['b']
>>> z
'c'
>>> *y
SyntaxError: can use starred expression only as assignment target
>>> print(*y)
b

カンマにいかほどの意味があるのかは現時点では不明。どうなってるのかなぁ
あと、なんでprintで表示できるのに単体ではダメなんだ?お前strオブジェクトなんだろ、前出て来いよ。
というかzは'c'だからstrオブジェクトだろうけど*yのオブジェクトって何だろう。

>>> type(z)
<class 'str'>
>>> type(y)
<class 'list'>
>>> type(*y)
<class 'str'>

あれ、strだた。ならなぜ出てきてくれないのか。ただ注意しなくてはいけないのは、次のような場合にはエラーになるということ。

>>> *a,=1,2
>>> a
[1, 2]
>>> type(*a)
Traceback (most recent call last):
  File "<pyshell#170>", line 1, in <module>
    type(*a)
TypeError: type() takes 1 or 3 arguments
>>> a=[1]
>>> type(*a)
<class 'int'>

このようにリストの要素が複数あれば、タイプを聞いてもエラー。単体ならばいける。

最後にもう一つ

>>> a=b=[1]
>>> b.append(3)
>>> a,b
([1, 3], [1, 3])
>>> a=b=[1]
>>> b+=[3]
>>> a,b
([1, 3], [1, 3])
>>> a=b=[1]
>>> b=b+[3]
>>> a,b
([1], [1, 3])

ここで、コメントしておきたいのは、なぜ最後の場合のみaに追加の命令が反映されていないのかということです。
奥が深いのか、それとも粗さの表れなのか、まー専門家ではないので良し悪しはわかりませんね。

*1:python3.3.2での実行結果です。python2.7.6では、エラーになりました。

【絶賛】就職活動中

なんとなく就活

 12月から4月まで就活がめんど…研究中心の生活を送っていました。
 4月にマターリSI系の企業廻ってたんですが、なーんか違うなと思い業界を変えてみることに。なんか、今、タブレットとかクラウドとか変革期らしく、企業の上の方の人たち&人事の人たちは、新しいものをどんどん取り入れていきたいって気持ちがあるらしい。どこのIT企業からもそういった上昇志向を感じた。でも、SI系の某会社なんかは社員面談で話した内容が「上がなんか言ってるけど、そういう革新についてくのめんどくせーわ」っと言った回答だった。無駄にワクワクしていた自分としては内心つまんなさそうな会社だなぁと思ってしまった。そのあとも数社廻ってみたが、どこの会社も昨今のSEイメージダウンを受けてか、ホワイトさアピールが半端なく、学生もそのあたりをよりどころとしている感じだった。
 5月現在は趣向を変えてweb・オープン系で就職活動してみることに。僕自身、情報系の人間ではないのだが、物理系の数値計算や社会科学系の授業でシミュレーションをするのでプログラムを書くわけです。ただ、職業準備としての勉強ではなくって、あくまで研究なのでやることが全然違う。そもそも周りの連中はコードなんて書かない。コード書かない人がSE,SIerになっていくのを見ると、どうやら自分はもっと違う仕事をやれるんじゃないか、そう思うようになった。

  • 業界研究ってなにすればいいんだろ

 業界研究ってやる必要あると思うんですけど、自分はあんまり積極的に今までやってませんでした。どうしても学校での研究内容の方が高尚な内容のような気がして馬鹿にしがち。でも、web系はフランクな業界紹介+作ってあそぼ的なノリの本があるようだ。ふむふむ。もっと言語や開発の工程について知っておいたほうがよいようだ。

Webサービスのつくり方 ~「新しい」を生み出すための33のエッセイ (Software Design plus)

Webサービスのつくり方 ~「新しい」を生み出すための33のエッセイ (Software Design plus)

Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)

Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)

 ただ、やっぱりなってみないことには実感わかない気がするなぁ。

Checkio "Three words"の解答

checkioで遊んでみた

プログラミング初心者アンドはてブ初心者です。
GWに特に予定もないのでpythonのcheckioで遊んでみました。

  • 問題

Let's teach the Robots to distinguish words and numbers.
You are given a string with words and numbers separated by whitespaces (one space). The words contains only letters. You should check if the string contains three words in succession.
Hints: You can easily solve this task with these useful functions: str.split, str.isalpha and str.isdigit.
Input: A string with words.
Output: True or False, a boolean.

  • 出力の例
checkio("Hello World hello") == True
checkio("He is 123 man") == False
checkio("1 2 3 4") == False
checkio("bla bla bla bla") == True
checkio("Hi") == False
  • ワイの回答
def checkio(a):
    found = False
    counter = 0
    for line in a.split():
        if line.isalpha():
            counter += 1
            if counter >= 3:
                found = True
                break
        if line.isdigit():
            found = False
            counter = 0    
    return found

初心者な回答って感じなのだろうか。
「三文字連続したらcheckioしてね」って文章ちゃんと読んでなかったのでグダりました


で上手い人のコードが見れるのがいいところなので見てみましょう。

  • クリエイティブな回答(Twisted, Puzzling, Obfuscated and Weird.)
checkio=lambda x:"www" in "".join('w' if w.isalpha() else 'd' for w in x.split())
  • クリアーな回答(Clear, Readable, Documented and Educational.)
def checkio(words):
    succ = 0
    for word in words.split():
        succ = (succ + 1)*word.isalpha()
        if succ == 3: return True
    else: return False
  • スピーディな回答(Speedy and Algorithmic. It should be fast.)
def checkio(words):
    k=0
    for word in words.split():
        if word.isalpha():
            k+=1
            if k==3:
                return True
        else:
            k=0
    return False

クリエイティブな回答みたいなワンライナー見るとpythonっぽいと思ってみたり。