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

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

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

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

Q&A

解決済

2回答

13463閲覧

python3: 文字と数字を含む文字列の数字でsortする方法

kujiraryo

総合スコア9

Python 3.x

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

0グッド

0クリップ

投稿2017/10/25 15:47

###前提・実現したいこと
python3で、[A1,A2,....,A100,B1,B2...,,B100]のようなリストの数字部分でsortがしたい。つまり [A1,B2,A2,B2,...A100,B100] というリストがほしい

###発生している問題・エラーメッセージ
最初に文字と数字に分割し、数字をint型に変換しsortするというやり方をやったのですが、もっと効率のいいやり方はないでしょうか?

(また文字と数字の分割もsplitするために間に"/"を入れましたが、これももっと良い方法があれば教えてください)

###ソースコード

python

1 2#テスト用の文字列作成 3A = ["A" + str(n) for n in range(1,101)] 4B = ["B" + str(n) for n in range(1,101)] 5AB = A + B 6import random 7random.shuffle(AB) # ついでにシャッフル 8 9#シーケンスを文字と数字で分割するために文字と数字の間に "/" を挿入する 10AB_list = [] 11for ab in AB: 12 for n in range(len(ab)-1): 13 if ab[n].isalpha() and ab[n+1].isdigit(): 14 AB_list += [ab.replace(ab[n]+ab[n+1] , ab[n]+"/"+ab[n+1])] 15 16#"/"でsplitするついでに数字をintに変換する 17ab_list = [] 18for x in AB_list: 19 ab_list.append([int(y) if y.isdigit() else y for y in x.split("/")]) 20 21#ab_lintの二列目(intタイプの数字)でsort、次に文字でsortする 22hoge = sorted(ab_list,key=lambda n:(n[1],n[0])) 23 24#一列目(str)と二列目(int)をjoinで連結 25ab = ["".join(map(str,x)) for x in hoge] 26

###試したこと
課題に対してアプローチしたことを記載してください

###補足情報(言語/FW/ツール等のバージョンなど)
使っているのはpython 3.6.2です

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

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

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

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

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

guest

回答2

0

ベストアンサー

正規表現を使い、対象の文字列の長さに関わらず数字部分の大小でソートするようにしてみました。

python

1import random 2import re 3A = ["BA" + str(n) for n in range(1,101)] 4B = ["B" + str(n) for n in range(1,101)] 5AB = A + B 6random.shuffle(AB) 7 8print(sorted(AB, key=lambda x:int((re.search(r"[0-9]+", x)).group(0))))

実行結果

$ python test.py ['B1', 'BA1', 'BA2', 'B2', 'BA3', 'B3', 'BA4', 'B4', 'BA5', 'B5', 'B6', 'BA6', 'BA7', 'B7', 'BA8', 'B8', 'B9', 'BA9', 'BA10', 'B10', 'B11', 'BA11', 'B12', 'BA12', 'BA13', 'B13', 'BA14', 'B14', 'B15', 'BA15', 'B16', 'BA16', 'BA17', 'B17', 'BA18', 'B18', 'B19', 'BA19', 'B20', 'BA20', 'B21', 'BA21', 'BA22', 'B22', 'BA23', 'B23', 'B24', 'BA24', 'B25', 'BA25', 'B26', 'BA26', 'BA27', 'B27', 'BA28', 'B28', 'BA29', 'B29', 'BA30', 'B30', 'B31', 'BA31', 'BA32', 'B32', 'BA33', 'B33', 'B34', 'BA34', 'BA35', 'B35', 'BA36', 'B36', 'B37', 'BA37', 'BA38', 'B38', 'BA39', 'B39', 'B40', 'BA40', 'BA41', 'B41', 'BA42', 'B42', 'B43', 'BA43', 'BA44', 'B44', 'B45', 'BA45', 'B46', 'BA46', 'B47', 'BA47', 'B48', 'BA48', 'B49', 'BA49', 'BA50', 'B50', 'B51', 'BA51', 'B52', 'BA52', 'BA53', 'B53', 'BA54', 'B54', 'BA55', 'B55', 'B56', 'BA56', 'BA57', 'B57', 'BA58', 'B58', 'B59', 'BA59', 'B60', 'BA60', 'BA61', 'B61', 'B62', 'BA62', 'B63', 'BA63', 'B64', 'BA64', 'B65', 'BA65', 'B66', 'BA66', 'BA67', 'B67', 'BA68', 'B68', 'B69', 'BA69', 'BA70', 'B70', 'B71', 'BA71', 'BA72', 'B72', 'B73', 'BA73', 'BA74', 'B74', 'BA75', 'B75', 'B76', 'BA76', 'B77', 'BA77', 'BA78', 'B78', 'B79', 'BA79', 'B80', 'BA80', 'B81', 'BA81', 'B82', 'BA82', 'BA83', 'B83', 'BA84', 'B84', 'B85', 'BA85', 'B86', 'BA86', 'BA87', 'B87', 'B88', 'BA88', 'B89', 'BA89', 'B90', 'BA90', 'BA91', 'B91', 'B92', 'BA92', 'BA93', 'B93', 'BA94', 'B94', 'BA95', 'B95', 'B96', 'BA96', 'BA97', 'B97', 'B98', 'BA98', 'BA99', 'B99', 'BA100', 'B100']

投稿2017/10/25 18:30

KojiDoi

総合スコア13671

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

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

0

アルファベット一文字と数値の組み合わせなら、次のように書けるかと。

Python

1>>> import random 2>>> 3>>> A = ['A' + str(i) for i in range(1, 11)] 4>>> B = ['B' + str(i) for i in range(1, 11)] 5>>> 6>>> AB = A + B 7>>> random.shuffle(AB) 8>>> 9>>> print(AB) 10['B3', 'A4', 'A7', 'B7', 'A10', 'B5', 'A1', 'B9', 'A5', 'A9', 'B10', 'A3', 'A6', 'A2', 'B2', 'B4', 'B1', 'B6', 'A8', 'B8'] 11>>> 12>>> AB.sort(key=lambda x: (int(x[1:]), x[0])) 13>>> print(AB) 14['A1', 'B1', 'A2', 'B2', 'A3', 'B3', 'A4', 'B4', 'A5', 'B5', 'A6', 'B6', 'A7', 'B7', 'A8', 'B8', 'A9', 'B9', 'A10', 'B10']

アルファベットが複数文字のときは、次のような関数を作ると良さそうですね。
(その気になればindex errorやrecursion errorを起こせますが、普通に使う分には問題ないです。)

Python

1def find_first_num(arg, i=0): 2 if not arg[0].isalpha(): 3 return i 4 return find_first_num(arg[1:], i+1)

こんな風に、英字と数字を分離できます。

Python

1>>> hoge = 'LouiS0616' 2>>> hoge[:find_first_num(hoge)] 3'LouiS' 4>>> hoge[find_first_num(hoge):] 5'0616'

投稿2017/10/25 16:18

編集2017/10/25 17:15
LouiS0616

総合スコア35660

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問