質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

972閲覧

文字列に11文字以上代入出来ない、ブランクを代入するとNoneと出力される

kiiti_shiraishi

総合スコア14

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2021/11/12 02:18

前提・実現したいこと

1、xmlfileを開いて内容を文字型行列に代入しようとしました。
1つの文字列は最大で13文字です。読み込んだxmlfileをパースする段階では13文字は正常に表示されます。しかしこれを文字型配列に代入後printすると
11文字しか表示されません。文字配列の定義に定数のint配列からstr配列に
変換しているので(numpyで文字配列が定義できるとのことですたので、調べましたが理解できず現在のコードで間に合わせています)変換の仕方がまずいのかと思っています。配列への代入の仕方も垢ぬけない感じです。

2、xmlファイルでブランク('')の箇所をパースすると'None'と取り込まれるので'None'の時はブランク('')にして代入しましたがプリントすると'None'がprintされます。調べて限りでは改行されるとなっていました。原因が判りません。

xmlfilefileをパースしている過程でプリントした内容

[['num', '1'],
['ns', 'AKT53'],
['nh', 'K82'],
['nd', 'QT3'],
['nc', 'Q6'],
['es', 'QJ7'],
['eh', 'T64'],
['ed', '976'],
['ec', 'J942'],
['ss', '98'],
['sh', 'AJ93'],
['sd', 'A85'],
['sc', 'T875'],
['ws', '642'],
['wh', 'Q75'],
['wd', 'KJ42'],
['wc', 'AK3'],
['vul', 'NONE'],
['deal', 'N'],
['num', '2'],
['ns', '87'],
['nh', '64'],
['nd', 'T52'],
['nc', 'AQ6532'],
['es', 'QT965'],
['eh', 'AT8'],
['ed', 'J64'],
['ec', '87'],
['ss', '4'],
['sh', 'J953'],
['sd', 'K9873'],
['sc', 'J94'],
['ws', 'AKJ32'],
['wh', 'KQ72'],
['wd', 'AQ'],
['wc', 'KT'],
['vul', 'NS'],
['deal', 'E'],
['num', '3'],
['ns', 'AKQJT98765432'], #これを配列に代入した箇所をプリント
['nh', None],
['nd', None],
['nc', None],
['es', None],
['eh', 'AKQJT98765432'],
['ed', None],
['ec', None],
['ss', None],
['sh', None],
['sd', 'AKQJT98765432'],
['sc', None],
['ws', None],
['wh', None],
['wd', None],
['wc', 'AKQJT98765432'],
['vul', 'NONE'],
['deal', 'W']]
#配列に代入後プリントした内容
AKQJT98765432 パースしたデータを表示、xmlファイルの内容が正しく表示されている
AKQJT987654   上記データ代入した配列を表示ん'32’が抜けている
None     ブランクを代入したが'None'と表示される

エラーメッセージ:無し
該当のソースコード

python

1import tkinter as tk 2import tkinter.filedialog as fd 3import xml.etree.ElementTree as ET 4import numpy as np 5 6global boardData 7global pd 8global exec 9 10InitData = np.full((65,18),1) 11boardData = InitData.astype(str) 12#xmlファイルの内容読込可孫タグ名、孫タグ内容表示可、 13#孫タグと内容はboard[n] n:0~Max孫ファイルの行 14def openFile(): 15 xfpath = fd.askopenfilename() 16 17 if xfpath: 18 global exec 19 global boardData 20 print(xfpath) 21 with open(xfpath, encoding='utf-8') as fin: 22 root = ET.fromstring(fin.read()) 23 24 board = [[e.tag, e.text] for e in root.findall('board/*')] 25 from pprint import pprint 26 pprint(board) 27 28 listNum = 0 29 exec = 0 30 while listNum <= len(board) - 1: #boardの最終行まで 31 if board[listNum][0] == 'num': 32 if board[listNum][1] == '': 33 listNum = 1300 #64boardでもWhileループ抜ける値 34 boardNum = int(board[listNum][1]) 35 exec = 1 36 37 elif board[listNum][0] == 'ns': 38 if board[listNum][1] == 'None': 39 boardData[boardNum][0] = '' 40 else: 41 boardData[boardNum][0] = board[listNum][1] 42 exec = 1 43 44 elif board[listNum][0] == 'nh': 45 if board[listNum][1] == 'None': 46 boardData[boardNum][1] = '' 47 else: 48 boardData[boardNum][1] = board[listNum][1] 49 exec = 1 50 51 elif board[listNum][0] == 'nd': 52 if board[listNum][1] == 'None': 53 boardData[boardNum][2] = '' 54 else: 55 boardData[boardNum][2] = board[listNum][1] 56 exec = 1 57 58 elif board[listNum][0] == 'nc': 59 if board[listNum][1] == 'None': 60 boardData[boardNum][3] = '' 61 else: 62 boardData[boardNum][3] = board[listNum][1] 63 exec = 1 64 65 elif board[listNum][0] == 'es': 66 if board[listNum][1] == 'None': 67 boardData[boardNum][4] = '' 68 else: 69 boardData[boardNum][4] = board[listNum][1] 70 exec = 1 71 72 elif board[listNum][0] == 'eh': 73 if board[listNum][1] == 'None': 74 boardData[boardNum][5] = '' 75 else: 76 boardData[boardNum][5] = board[listNum][1] 77 exec = 1 78 79 elif board[listNum][0] == 'ed': 80 if board[listNum][1] == 'None': 81 boardData[boardNum][6] = '' 82 else: 83 boardData[boardNum][6] = board[listNum][1] 84 exec = 1 85 86 elif board[listNum][0] == 'ec': 87 if board[listNum][1] == 'None': 88 boardData[boardNum][7] = '' 89 else: 90 boardData[boardNum][7] = board[listNum][1] 91 exec = 1 92 93 elif board[listNum][0] == 'ss': 94 if board[listNum][1] == 'None': 95 boardData[boardNum][8] = '' 96 else: 97 boardData[boardNum][8] = board[listNum][1] 98 exec = 1 99 100 elif board[listNum][0] == 'sh': 101 if board[listNum][1] == 'None': 102 boardData[boardNum][9] = '' 103 else: 104 boardData[boardNum][9] = board[listNum][1] 105 exec = 1 106 107 elif board[listNum][0] == 'sd': 108 if board[listNum][1] == 'None': 109 boardData[boardNum][10] = '' 110 else: 111 boardData[boardNum][10] = board[listNum][1] 112 exec = 1 113 114 elif board[listNum][0] == 'sc': 115 if board[listNum][1] == 'None': 116 boardData[boardNum][11] = '' 117 else: 118 boardData[boardNum][11] = board[listNum][1] 119 exec = 1 120 121 elif board[listNum][0] == 'ws': 122 if board[listNum][1] == 'None': 123 boardData[boardNum][12] = '' 124 else: 125 boardData[boardNum][12] = board[listNum][1] 126 exec = 1 127 128 elif board[listNum][0] == 'wh': 129 if board[listNum][1] == 'None': 130 boardData[boardNum][13] = '' 131 else: 132 boardData[boardNum][13] = board[listNum][1] 133 exec = 1 134 135 elif board[listNum][0] == 'wd': 136 if board[listNum][1] == 'None': 137 boardData[boardNum][14] = '' 138 else: 139 boardData[boardNum][14] = board[listNum][1] 140 exec = 1 141 142 elif board[listNum][0] == 'wc': 143 if board[listNum][1] == 'None': 144 boardData[boardNum][15] = '' 145 else: 146 boardData[boardNum][15] = board[listNum][1] 147 exec = 1 148 149 elif board[listNum][0] == 'vul': 150 boardData[boardNum][16] = board[listNum][1] 151 exec = 1 152 153 elif board[listNum][0] == 'deal': 154 boardData[boardNum][17] = board[listNum][1] 155 exec = 1 156 157 elif exec == 0: 158 print('エラ-') 159 boardNum = 0 160 listNum += 1 161 print(board[39][1]) #boardData[3][0]代入した元のパースした内容をprint→ 162 print(boardData[3][0]) #13文字が入っている場所をprint 163 print(board[40][1]) #ブランクを代入した箇所をprint 164 165 166root = tk.Tk() 167root.geometry("400x350") 168btn = tk.Button(text="ファイルを開く", command = openFile) 169btn.pack() 170tk.mainloop()

試したこと

boardData = InitData.astype(str)についてnetで調べましたが情報が得られず打つ手がない状態です。

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

既に解決済みですが、別回答として投稿します。

XML をパースする部分ですが、e.text if e.text else '' とすることで値を持たないノードを読み込む際には None''(empty string) に変換します。

python

1 #board = [[e.tag, e.text] for e in root.findall('board/*')] 2 board = [[e.tag, e.text if e.text else ''] for e in root.findall('board/*')]

次に、num ノードの値が 1 から始まっているので、配列のインデックス(0始まり)に補正します。

python

1 while listNum <= len(board) - 1: #boardの最終行まで 2 if board[listNum][0] == 'num': 3 if board[listNum][1] == '': 4 listNum = 1300 #64boardでもWhileループ抜ける値 5 # boardNum = int(board[listNum][1]) 6 boardNum = int(board[listNum][1]) - 1

インデックスの補正で boardData の行番号がずれるので、それを変更します。

python

1 #print(boardData[3][0]) #13文字が入っている場所をprint 2 print(boardData[2][0]) #13文字が入っている場所をprint

以上の変更を行って実行すると以下の様に表示されます。

AKQJT98765432 AKQJT98765432

以下の説明は間違いです。正しくは bsdfan さんのコメントをお読み下さい。

===== ここから =====
ちなみに、numpy 1.21.4 ではデフォルトで 21 バイト確保されるので当該の問題は発生しません。

python

1>>> import numpy as np 2>>> np.__version__ 3'1.21.4' 4>>> InitData = np.full((65,18),1) 5>>> boardData = InitData.astype(str) 6>>> boardData 7array([['1', '1', '1', ..., '1', '1', '1'], 8 ['1', '1', '1', ..., '1', '1', '1'], 9 ['1', '1', '1', ..., '1', '1', '1'], 10 ..., 11 ['1', '1', '1', ..., '1', '1', '1'], 12 ['1', '1', '1', ..., '1', '1', '1'], 13 ['1', '1', '1', ..., '1', '1', '1']], dtype='<U21') 14>>> boardData[0][1] 15'1' 16>>> boardData[0][1] = '012345678901234567890' 17>>> boardData[0][1] 18'012345678901234567890'

===== ここまで =====

後々の事を考えると、固定長で確保するよりは dtypeobject を指定する方が良いかもしれません。

python

1#InitData = np.full((65,18),1) 2#boardData = InitData.astype(str) 3 4boardData = np.full((65,18), '', dtype=object)

余談

pandas には pandas.read_xml というメソッドがあるので、そちらを使うと良いかもしれません。

python

1import pandas as pd 2 3xfpath = 'data.xml' 4 5df = pd.read_xml(xfpath, xpath='board') 6df.fillna('', inplace=True) 7 8boardData = df.to_numpy(copy=True) 9print(f'boardData:\n{boardData}\n') 10print(f' Type: {type(boardData)}') 11print(f' DataType: {type(boardData.dtype)}') 12print(f' Shape: {boardData.shape}') 13 14boardData[2][1] = boardData[2][1] * 5 15print(f'\nboardData[2][1]: {boardData[2][1]}') 16 17_ = """ 18boardData: 19[[1 'AKT53' 'K82' 'QT3' 'Q6' 'QJ7' 'T64' '976' 'J942' 98.0 'AJ93' 'A85' 20 'T875' '642' 'Q75' 'KJ42' 'AK3' 'NONE' 'N'] 21 [2 '87' '64' 'T52' 'AQ6532' 'QT965' 'AT8' 'J64' '87' 4.0 'J953' 'K9873' 22 'J94' 'AKJ32' 'KQ72' 'AQ' 'KT' 'NS' 'E'] 23 [3 'AKQJT98765432' '' '' '' '' 'AKQJT98765432' '' '' '' '' 24 'AKQJT98765432' 'J94' '' '' '' 'AKQJT98765432' '' 'W']] 25 26 Type: <class 'numpy.ndarray'> 27 DataType: <class 'numpy.dtype[object_]'> 28 Shape: (3, 19) 29 30boardData[2][1]: AKQJT98765432AKQJT98765432AKQJT98765432AKQJT98765432AKQJT98765432 31"""

投稿2021/11/12 04:31

編集2021/11/12 07:50
melian

総合スコア20655

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

bsdfan

2021/11/12 04:44

> ちなみに、numpy 1.21.4 ではデフォルトで 21 バイト確保されるので当該の問題は発生しません。 この部分は、バージョンではなくプラットホームに依存と思われます。(numpyのintのビット数がプラットホーム依存だから) intをstrにしたとき、32bitの場合は最大で11文字、64bitの場合は最大で21文字あればいいようです。 また、ユニコード文字列なので1文字≠1バイト。
melian

2021/11/12 04:47

!、ありがとうございます。
kiiti_shiraishi

2021/11/15 05:49

numpy 1.21.2だったので再インストールしましたが、同じバージョンがインストールされました。 今はWindows8.1 64ビットです。
kiiti_shiraishi

2021/11/15 06:19

前にVBを勉強しましたが、str型は通常は1変数の長さは気にしなくてもよかったんですけどpythonは注意しないといけないことが判りました。ありがとうございます。
guest

0

自己解決

文字配列に文字が11文字以上代入出来ない件、文字列定義を
boardData = np.array(['1111111111111']6518).reshape(65,18)とすることで解決しました。
質問投稿「Pythonで文字配列の定義の方法」のppaulさんの解答を参考にしました。

投稿2021/11/12 03:44

kiiti_shiraishi

総合スコア14

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

bsdfan

2021/11/12 04:15

自己解決されているので、コメントにしますが、下記でもOKです。 boardData = np.full((65, 18), '1111111111111') または boardData = np.full((65, 18), '', dtype='U13')
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問