プロが教えるわが家の防犯対策術!

python超初心者です(3時間目)。pythonで以下のようなランダム数列を生成させるにはどうしたらいいのでしょうか?

最終結果のイメージ(16進数8桁の数列x20行):
0 : c39a29eb
1 : b26cc9bb
2 : 4c494e47
...
19: 93c85836


以下のようにコードを組んでみたのですが、
> tmp = ws.join(list)
> TypeError: sequence item 0: expected string, int found
のようなエラーが出てしまいます。どうやら数字を連結しようとしてるのでダメなのかな?と思っています。

========================================
#! /usr/bin/python

import random
list = []
ws = ""

for i in range (20):
print i, ":",
for j in range(8):
list.append(random.randint(0,15))
tmp = ws.join(list)
print tmp
list = []
tmp = ""
========================================
※ printでは必ずスペースが入ってしまうので、それを嫌う場合配列に入れて、要素を連結させなくてはならない、とwebにあったので、その方向で試してみました。
※ また、ここではあくまでrandom を使用し、一文字(0,1,2,...E,F)づつ出力させたいと思っています。


なお、perlでは以下のように書くことができたのですが...
========================================
#! /usr/bin/perl

for($i=0; $i<20; $i++){
printf ("%-02s: ", $i);
for($j=0; $j<8; $j++){
printf("%x", int(rand(15)) );
}
print "\n";
}
========================================

※ んー第二言語としてpythonを学習してみていますが道のり険しそうです(やっぱrubyにしようか)...

宜しくお願い致します。

A 回答 (3件)

Pythonはインデントが重要なのですが、ここでは消されてしまいます。


全角スペースとか適当な文字を使って代用するようにしてください。

さて。
数値は文字列ではありません。
joinは文字列を連結するものですが、数値を自動で文字列化するようなことはしません。
Pythonでは、型付けは結構厳しいです。

ところで、そのPerlの中で %xを使って数値を文字列に変換していますよね。
Pythonでも同じように文字列化すればよいのです。
フォーマット文字列 % 単独の値、またはシーケンス
が,Perlの sprintf(フォーマット文字列, 値...) と同等ですので
list.append( "%X" % random.randint(0,15))
とすれば、listのは16進の文字列で格納されるので、joinで連結できます

#! /usr/bin/python
import random
# forの範囲などで使うなら、リストを作るrangeより、イテレータを作るxrangeの方が効率的
for i in xrange (20):
 list = []
 for j in xrange(8):
  list.append('%x' % random.randint(0,15))
# 後に使わないのなら、直接書いてもよいでしょう。
# 文字列リテラルも「オブジェクト」なので、下のjoinのような書き方もできます。
 print '%02d:%s' % (i, ''.join(list))

ちなみに、2.6以降ではprintの仕様変更がありましたので、そのPerlのスクリプトをPythonではこう書けます。

#! /usr/bin/python
from __future__ import print_function #2.6で3仕様のprintを使用するのに必要。3では不要
import random

for i in xrange(20):
# もとは"%-02s"だけど、これは文字列と数値の違いのないPerlだからできること
 print( "%02d:" % i , end='' )
 for j in xrange(8):
  print( "%x" % random.randint(0,15) , end='')
# endの指定がなければ改行付き。表示文字列指定がなければ改行だけ
 print( )
    • good
    • 0
この回答へのお礼

お礼遅れましたが本当にどうもありがとうございます。
型定義が厳しい、ということを認識しました。  list.append('%x' % random.randint(0,15)) という使い方、今回学びました。

一冊ざっと読んでみて色々と疑問がでてきています。また宜しくお願いいたします

お礼日時:2010/06/24 23:37

こういうやり方もあるということで。


メソッドの動作などはマニュアルで確認してください。

import random

for i in range(20):
____print ''.join([ random.choice("0123456789abcdef") for z in range(8) ])

#行頭の空白を _ に置き換えているので注意

実行するとこうなります↓

ca395f64
7f0a7886
46668b07
9987ca40
d1db01ba
d58e89fe
51c4b65e
244f5a9c
64e0bb40
00bd7a5d
040dd325
5f0d6bbd
04919c6a
84497900
303a6cc0
2697a993
e926bdf3
9c8c9b70
b22facce
d4362487
    • good
    • 1
この回答へのお礼

お礼遅れましたがどうもありがとうございます。
手元の本(みんなのPython)によると「リスト内包表記」と理解しました。

有難うございます。

お礼日時:2010/06/24 23:41

そのperlとだいたい同じに書けますよ。


(全角スペースでインデントしてます、注意)

==============================================
#! /usr/bin/python

import random
import sys

write = sys.stdout.write

for i in xrange (20):
 write("%-02d : " % i)
 for j in xrange(8):
  write("%x" % random.randint(0,15))
 print

==============================================
%記号を使うことで、書式文字列を簡単に出力できるのが便利です。
rubyも良いと思いますが、pythonを捨てるにはまだ早いです。正規表現は面倒ですが、なかなか良いものですよ。
    • good
    • 0
この回答へのお礼

お礼遅れましたがどうもありがとうございます。
前の方も書かれていた、%記号の型表記の発想が完全に抜けていたようです。
ありがとうございます。

正規表現はまだ攻略できていませんが、考え方を勉強中です。またどうぞ宜しくお願いいたします。

お礼日時:2010/06/24 23:39

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!