• 締切済み

pythonの文字列のインデックスについて

s='あいうえお' x=s[1:2:1] print(x) 開始インデックス1、終了インデックス2、ステップ1です。 この結果は"い”となります。あいうえお = 0 1 2 3 4 なのでs[1:..]が”い”に相当するのは分かります。s[1:2:..]の2はどういう風に解釈するのでしょうか。 簡単なはずなのですが混乱してしまいました。よろしくお願いします。

  • Python
  • 回答数6
  • ありがとう数4

みんなの回答

  • ysumie
  • ベストアンサー率0% (0/0)
回答No.6

開始インデックス、終了インデックス、ステップを、 a,b,cと呼ぶと、 インデックスのa番目から、b-1番目までを、cステップずつ になります。 終了インデックスが、マイナス1なのが、ややこしいですよね。

  • n-jun
  • ベストアンサー率33% (959/2873)
回答No.5

質問自体より既出の回答の返信内容を見ていると、 >簡単なはずなのですが と感じているのにちょっとビックリです。 正直返信内容を見ていたら 「いっそPythonの開発者にどうしてそうなるように作ったのか!」と 聞いてみる方が早いのでは?と感じましたね。 開発されている状況に応じてそれを身につけ組んでいくしか一般的な人はやるしかない と改めて感じさせられました。 どうしてもその部分を仕様として覚えるのではなく、どうしてそのような仕様になったのかを知るとしたら、答えられるのはやっぱ開発元になるのではないでしょうか?

skmsk1941093
質問者

お礼

回答ありがとうございます。プログラム言語も言語なのでなぜ、そうなるのかを問うことはできない、なぜ鉛筆をpencilというのか問うことはできない、ということと同値である、ということなのでしょうか。鎌倉幕府が1192年というのも”なぜ”はほぼ受け付けません。これらは事実を飲み込むしか仕方がありません。そういうことなのでしょうか。 しかし、機能を定式化(パターン化)することはできるのではないかと思っています。覚え方と言ってもいいのかもしれません。実験=帰納的であり(事実を飲み込む)、定式化(パターン化)=演繹的です。 s='あいうえお' x=s[i:j:k] この時に右辺を関数で表示するとどうなるのかということなのですが。実例を示すことではなく。 もし無理やり解釈するなら以下の通りです。(多分違うだろうと思いますが、関数を言葉で表示しているつもりです。こういうことを確認したいということなのですが) --- s[1:2:1]では、文字列sのインデックス1から文字列の最初からの2個目までを1つづつ示すという意味である。 s='あいうえお'に当てはめると文字列sのインデックス1は'い'であり、先頭から2個目はすなわち'い'となり、そこまで飛び0で出すのだから結局'い'のみとなる。 ということは、s[i:j:k]とは文字列sのインデックスiから文字列の個数jまでを(k-1)個飛びに取り出すということである。 ※なおインデックスはゼロから始まるが、個数は1から始まる。 ※この解釈ならi,j,kは正の整数のみでしか成立しません。負の場合は別途定義しなおす? ---

  • qzl
  • ベストアンサー率0% (0/0)
回答No.4

もう私の回答に対して返答するの辞めてくださいね

  • qzl
  • ベストアンサー率0% (0/0)
回答No.3

1+1が2になる理由が解りません、この証明方法を教えてくださいなんてことを今調べてたらキリがなくなります もう少し掘り下げてプログラミングを理解したいという話ならPythonより多くの関数を自力で作らなければいけないC言語とかのほうが良いと思いますけどね C言語では文字列を配列として扱うことになるのでPythonでいうところのスライスの仕組みが少しは理解できるでしょうね。

  • qzl
  • ベストアンサー率0% (0/0)
回答No.2

お礼拝見しました あれこれ試してご自身で検証するということをまったくしないのですね

skmsk1941093
質問者

お礼

ご指摘ありがとうございます。 実際の動作の確認はとれるのですが、理解の方法がわからないという質問なのです。あれこれ試して実際にそうなっているのだからそれを丸呑みせよ、という方法もあるでしょうけれど。実際の動作確認というのであればこの質問の前にたっぷりやっており、どう理解したらよいかわからないということが質問の主旨なのですが。

  • qzl
  • ベストアンサー率0% (0/0)
回答No.1

1から1(間隔)ずつ2番目までです x[1:4:2]とやれば"いえ"となり 1から1つ飛ばし(2間隔)で4番目までと分かりやすいと思います スライスのいろいろです、文字列と配列は同じ理屈ですので以下を参考にどうぞ #以降は出力結果です num = [40, 50, 60, 70, 80, 90] num[1:4] # [50, 60, 70] num[:2] # [40, 50] num[:-1] # [40, 50, 60, 70, 80] num[3:] # [70, 80, 90] num[-3:] # [70, 80, 90] num[::2] # [40, 60, 80] num[::-2] # [90, 70, 50] num[::-1] # [90, 80, 70, 60, 50, 40] num[-2::-1] # [80, 70, 60, 50, 40] num[0:5:2] # [40, 60, 80]

skmsk1941093
質問者

お礼

回答ありがとうございます。確認です。 x[1:4:2] は1から2間隔で4番目まで、ということなので、 x[l:m:n] はlからn間隔でm番目まで、という一般化でいいでしょうか。 文字列を配列番号0から始まる数で標記してその数をインデックスとします。 この”m番目”ですが、インデックスとしてはm-1ということになるので、 番目をなくしてインデックスで標記すると、 x[l:m:n] はインデックスlからインデックスm-1までn間隔でという理解なのですが。ただし、そうすると負のインデックスはないのでそこはどうするかという問題は残りますが。nについて負だったら逆に戻ると解釈すると。l,mが負ってどういうことなのかという疑問が残ります。どう考えるのでしょうか。

関連するQ&A

  • PythonでUTF8の文字列をリストに入れると文字化けする

    PythonでUTF8の文字列をリストに入れると文字化けして、困っています。 以下、サンプルコードです。 a='あ' print a cmd=[] cmd.append(a) print cmd 結果は以下のようになります。 あ ['\xe3\x81\x82'] 文字化けしないようにリストに格納するにはどうすればよいでしょうか。 また、最終的にやりたいことは、リストの内容をLinuxのコンソールに出力することです。 Linux上で、$'\xe3'$'\x81'$'\x82'とすると'あ'という風に認識してくれるので、このようにリストに格納されれば良いと思っているのですが、良い方法はあるでしょうか。 よろしくお願いします。

  • 正規表現:対応する文字列A~文字列Bの検索(入れ子あり)

    いつもお世話になります。 以下のように (??{}) というのを使うと正規表現を再帰することによって入れ子があっても対応するカッコにマッチできることが分かりました。 以下のプログラムでは < から対応する > までを抜いています。 #! perl # betweenBracket -- < から対応 > までを抜く # 全角ブランクで字下げを表現しています。 $re = qr/  <   [^<>]*   (?:    (??{$re})    [^<>]*   )*  > /x; while(<DATA>) {  chomp;  for (/$re/g) {   print "$_ ";  }  print "\n"; } __DATA__ I <love> you I <love> <you> <I <love> <you>> 実行結果: <love> <love> <you> <I <love> <you>> これですが、<、>のような1文字のカッコではなくて文字列による開始~終了でもできるでしょうか。 具体的に言うと &lt; から &gt; までと言う風にしたいです。 #! perl # betweenEntity -- &lt; から対応 &gt; までを抜く ・・・???・・・・ __DATA__ I &lt;love&gt; you I &lt;love&gt; &lt;you&gt; &lt;I &lt;love&gt; &lt;you&gt;&gt; 実行結果: &lt;love&gt; &lt;love&gt; &lt;you&gt; &lt;I &lt;love&gt; &lt;you&gt;&gt; よろしくお願いします!

    • ベストアンサー
    • Perl
  • 【至急】文字を点滅させる方法は?

    質問します。 下記のプログラムにおいて、 13 PRINT "只今、計算中です。少々お待ち下さい。" 14 PRINT "計算終了後、下記に結果を表示します。" の部分だけを点滅させたいのですが、色が変わる変化しかしません。COLOR 2と書けば点滅するはずですよね? 1 CLS 2 REM 乱数を用いてサイコロ(6面体ダイス)を再現。12000回振って各自がほぼ2000回ずつ出るようなサイコロを目指す。 10 INPUT "乱数系列の値をいくつに設定しますか" ;X 13 PRINT "只今、計算中です。少々お待ち下さい。" 14 PRINT "計算終了後、下記に結果を表示します。" 20 RANDOMIZE X 30 DIM DICE(6) 40 FOR T=1 TO X 50 LET N=1+INT(6*RND) 60 FOR I=1 TO 6 70 IF N=I THEN LET DICE(I)=DICE(I)+1 80 NEXT I 90 NEXT T 100 PRINT 110 FOR J=1 TO 6 120 PRINT J;"の目は"; DICE(J);"回出ました。" 130 NEXT J 140 END よろしくお願いします。

  • Rubyでメタ検索プログラムを見よう見まねで書いていますが、結果がバイナリ文字列で表示されます。

    Rubyで下記のようなプログラムを書いています。ある検索サイトに対してメタサーチ的なものを実現したいと思い、見よう見まねで作っています。問題は結果が出るものの、日本語で本来出るべき結果部分がバイナリ文字列で表示されます。例えば、?216?241?227?303?201o?202?277といった感じです。おそらく初歩的な質問になってしまうと思いますが、教えていただけると助かります #!/usr/bin/ruby require "socket" require "cgi" c = CGI.new text = c["t"] s = TCPSocket.new("www.xxx.com", 80) s.write "GET /xxx/index.php?word_in=xxx HTTP/1.0?r?n?r?n" print "Content-Type: text/html?n?n" result=s.read.split(/?<li?>/) p result[1] print "<br>" print "</body></html>"

  • python超初心者です(3時間目)。pythonで以下のようなランダ

    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にしようか)... 宜しくお願い致します。

  • VBScriptでExcel(インデックスが…)

    昨日も質問をしたばかりで、自分でも情けないのですが… (すみません、2つ分からないことがあります。) VBScriptでExcelのファイルの中身を 別のファイルにコピーするプログラムを作りました。 見にくい変数名で申し訳ないのですが、 これを実行すると、17行目で 「インデックスが有効範囲にありません」 というエラーメッセージが出て止まってしまいます。 しかし、ここで「Set」しているファイルは 「Original.xls」というファイルなのですが、 シートは20個あります。 この20個という数は、絶対にあり得ない数で、 読み込み側のファイルのシートは最大で17個ですので、 数が足りないはずはありません。 だいたい、「インデックス…」というのは配列変数と思って 処理しているのでしょうか? 何より、プログラムの最初の方に 「On Error Resume Next」を置くと、 このプログラムの所期の目的である、 読み込んだファイルの中身を 「Original.xls」にペースとして ファイル名をかえて保存する というのは実現できています。 2つ目の問題は、 22行目から24行目で 「Original.xls」の不要なシートを削除しているのですが、 途中に「MsgBox」を置いて、 「s」や「i」の値を調べてみても問題はないのに、 シートが1つしか残りません。 例えば、読み込んだファイルのシートの数が3なら 「s + 1 = 4」ですから、この「For~Next」ループは 「4~20」までの17回実行され、 その間、常に4番目のシートを削除し続け、 結果として、必要な1~3のシートが残るはずなのですが、 常に19個削除されてしまいます。 本来は、「Original.xls」のシートの数は1つにしておいて、 必要な数だけ、その1つのシートをコピーで増やしたかったのですが、 それも分からず、仕方なしにこんなやり方をしました。 やはり、そのやり方でないと、ダメなのでしょうか? 以上、ややこしい質問で申し訳ないのですが、 お分かりの方がおられましたら、お教えください。 Option Explicit '01 Dim d, i, s, t, u, v, w, x, y, z '02 Set t = CreateObject("Scripting.FileSystemObject") '03 Set u = t.GetFolder(".") '04 Set v = CreateObject("Excel.Application") '05 Set w = v.Workbooks.Open(u & "\Result\Original.xls") '06 '07 v.Application.DisplayAlerts = False '08 v.Visible = False '09 '10 For Each d In u.Files '11 If t.GetExtensionName(d.Name) = "xls" Then '12 Set x = v.Workbooks.Open(u & "\" & d.Name) '13 s = x.Worksheets.Count '14 For i = 1 to s '15 Set y = x.Worksheets(i) '16 Set z = w.Worksheets(i) '17 z.Name = y.Name '18 y.Range("A1:U55").Copy z.Range("A1") '19 y.Range("AB1:AF55").Copy z.Range("V1") '20 Next '21 For i = s + 1 to 20 '22 .Worksheets(s + 1).Delete '23 Next '24 x.SaveAs(u & "\o_" & d.Name) '25 w.SaveAs(u & "\Result\" & d.Name) '26 x.Close '27 End If '28 Next '29 '30 v.Quit '31 Set z = Nothing '32 Set y = Nothing '33 Set x = Nothing '34 Set w = Nothing '35 Set v = Nothing '36 Srt u = Nothing '37 Set t = Nothing '38 '39 MsgBox("Finished") '40 よろしく、お願い致します。

  • VARIANCEとμの関係? Eの解釈?

    Var(X) = E( X-μ)^2 = E(X^2) - 【E(X)】^2  Eとはなんなのか・・・  これは、SUM、という意味なのか、それとも平均を求めろという意味なのか・・・。混乱しています。 Eの意味が、期待値であるというのは知っているのですが、 特にVARの公式で、E()とやられてしまうと、このEをどのように扱ったらよいのか、理解に苦しみます。 Eをどう解釈したらよいでしょうか? ■また Var(X) = E( X-μ)^2 という数式についてですが、  【VAR は、 ( X-μ)^2 の平均だ】 といった解釈でも大丈夫でしょうか?  ・・・なぜなら、E(X) = μ という 風にも書いてあったので・・・。 よろしくお願いいたします。   

  • 行・列に隣り合う配列の要素を調べたい

    C言語でパズル的なものを作成していますが、 解らないことがありこちらで質問させていただきます。 何卒、よろしくお願いします。 ――――――――――――――――――― char list[7][7] = {   {0,0,0,0,0,0,0},   {0,0,0,0,0,0,0},   {0,0,0,0,1,0,0},   {0,0,1,9,1,0,0},   {0,0,0,1,1,0,0},   {0,0,0,1,0,1,0},   {0,0,0,0,0,0,0}, }; int result[7*7][2]; // [n][0]=x, [n][1]=y 例えば、上記のような配列があり、 list[4][4]の位置から探索開始したとします。 (解り易くするため仮に'9'を指定しています) このlist[4][4]から「上下左右」に調べ、 '1'があればそこから更に上下左右に調べるといった感じで、 '1'で繋がってる配列の要素番号を抜き出したいのです。 例えばlist[4][5]が'1'であるため、 次にlist[5][5]とlist[4][6]を調べます。 また、list[3][4]の上下左には'1'が無いのでこの配列の探索は終了となります。 上記例でいえば、'x'の点が求めたい要素番号に該当します。 char list[7][7] = {   {0,0,0,0,0,0,0},   {0,0,0,0,0,0,0},   {0,0,0,0,x,0,0},   {0,0,x,9,x,0,0},   {0,0,0,x,x,0,0},   {0,0,0,x,0,1,0},   {0,0,0,0,0,0,0}, }; このような処理をする上で、 何か良いアルゴリズム等は方法はないでしょうか?

  • Fortran90のプログラムについて

    大学で卒論のためにFortran90でランダムウォークのプログラムを作ってるんですが…2週間悩んでるんですが、できないところがあります。 「1次元のランダムウォークにおいて、ステップ数Nとxの値を与えたときのすべての可能な歩行を数え上げるプログラムを書け」というものです。 直接ステップ数を書き込んだプログラムを基にして任意のステップ数を入力するプログラムを作ってみたんですが、うまくいきません。 integer :: a(100,20), x, i1, i2, i3 x = 0 do i1 = -1, 1, 2;do i2 = -1, 1, 2;do i3 = -1, 1, 2 x = x + 1 a(x, 1) = i1;a(x, 2) = i2;a(x, 3) = i3 end do;end do;end do end が基にしたプログラムです。これはステップ数が'3'なので実行結果は「-1-1-1,-1-11,-11-1,-11-1,-111,1-1-1,11-1,111」というxの変位の仕方が出ます。 integer, allocatable :: a(:,:) integer :: i, n, x, l print *, 'ステップ数を入力:'; read *, n allocate(a(n, 2**n)) do l = 1, n do i = -1, 1, 2 x = x + 1 a(x, l) = i end do end do end という風に作ってみたんですが、'3'を入力しても同じ結果が出ません。わかりにくい文章で申し訳ないですがどなたかご教授お願いします。

  • 配列の使い方がわかりません

    n=1~20 s=n(n+1)(2n+1)(3n^2+3n-1)/30 のsの結果を数表にする問題で、 n  s    n   s   1  _   11 _ 2  _  12 _ ・      ・ ・      ・ ・      ・ 10 _  20  _ というような表示をしたくて、配列を用いてしてるんですが、うまくいきません。どなたか、教えてください。 public class suuhyou{ public static void main(String[] args){ int a=0,b=0,c=0,d=0,s=0; int[] x = new int[50]; for(int n=1;n<=50;n++){ a = n; b = n + 1; c = 2 * n + 1; d = 3 * n * n + 3 * n - 1; s = a * b * c * d / 30; int x[n] = s; } for(int k=1;k<=10;k++){ System.out.print ( k + ":" + x[k] +","); System.out.print ((k+10) + ":" + x[k+10]+","); System.out.print ((k+20) + ":" + x[k+20]+","); System.out.print ((k+30) + ":" + x[k+30]+","); System.out.println((k+40) + ":" + x[k+40]); } } } 自分でやっていたら、最後はこんな風にだんだんめちゃくちゃになってしまいました。このときはnが50まででやってます。お願いします。