シーケンス対象となっているリストは、popで取り出しても、内容が不変だから、その原因がどうしてなのかということと、順に取り出す方法を知りたい。
import itertools
value_text = [['an applean orange', 'an orangean apple'], ['a pena ball', 'a balla pen']]
value_text = itertools.product(*value_text)
solid_text = ['I have ', '.You have ', '.']
copy_text = solid_text[:]
text_seq = []
new_seq = []
for k,text in enumerate(value_text):
length = len(solid_text) + len(text)
pri_text = list(text[:])
for j in range(length):
if j%2 == 1:
a = list(pri_text).pop(0)
print("pri_textの値:",list(pri_text))
print(a,"が入りました。")
text_seq.append(a)
else:
b = solid_text.pop(0)
print("solid_textの値",solid_text)
print(b,"が入りました。")
text_seq.append(b)
new_seq.append(text_seq)
solid_text = copy_text[:]
text_seq = []
print("結果",new_seq)
このコードを実行することによる狙い。
偶数ごとにsolid_text
、奇数ごとにvalue_text
を順次取り出しては新しいリスト入れ込んでいき、一つのシーケンスへと合体させていく処理を実装したいです。
例えば、最初のシーケンス実行後は、
['I have ','an applean orange','.You have ','a pena ball','.']
という状況を作りたいです。
そのためには、if j%2 == 1:
以下にある、(pri_text).pop(0)
で、少なくともこのpri_text
の内容が、順次取り出されて少なくなっていってくれる必要があります。
ところが、pop
メソッドの利点である、漸減処理ができません。
したがって、pri_text
の内容は、どんなに実行しても、元の内容のままであります。
おかげで、結果はこうなります。
結果
[['I have ', 'an applean orange', '.You have ', 'an applean orange', '.'], ['I have ', 'an applean orange', '.You have ', 'an applean orange', '.'], ['I have ', 'an orangean apple', '.You have ', 'an orangean apple', '.'], ['I have ', 'an orangean apple', '.You have ', 'an orangean apple', '.']]
強制的に実現するに当たり、コードを以下のようにしました。
結果は、望む形となりました。
強制的実現のためのコード:
import itertools
value_text = [['an applean orange', 'an orangean apple'], ['a pena ball', 'a balla pen']]
value_text = itertools.product(*value_text)
solid_text = ['I have ', '.You have ', '.']
copy_text = solid_text[:]
text_seq = []
new_seq = []
for k,text in enumerate(value_text):
length = len(solid_text) + len(text)
pri_text = list(text[:])
for j in range(length):
if j == 1:
a = list(pri_text).pop(0)
print("pri_textの値:",list(pri_text))
print(a,"が入りました。")
text_seq.append(a)
elif j == 3:
a = list(pri_text).pop(1)
print("pri_textの値:",list(pri_text))
print(a,"が入りました。")
text_seq.append(a)
else:
b = solid_text.pop(0)
print("solid_textの値",solid_text)
print(b,"が入りました。")
text_seq.append(b)
new_seq.append(text_seq)
solid_text = copy_text[:]
text_seq = []
print("結果",new_seq)
結果(望む形):
[['I have ', 'an applean orange', '.You have ', 'a pena ball', '.'], ['I have ', 'an applean orange', '.You have ', 'a balla pen', '.'], ['I have ', 'an orangean apple', '.You have ', 'a pena ball', '.'], ['I have ', 'an orangean apple', '.You have ', 'a balla pen', '.']]
質問
望む形になるために、pop
が漸減的処理を行ってほしいのですが、そうならない理由はなぜでしょうか?
コードを実行していただくとわかりますが、solid_text
と、pri_text
は、このように変化します。
solid_text:
solid_textの値 ['.You have ', '.']
solid_textの値 ['.']
solid_textの値 []
pri_text:
pri_textの値: ['an applean orange', 'a balla pen']
pri_textの値: ['an orangean apple', 'a balla pen']
以下ずっとこれ。
このため、pop(0)
から順に取り出そうとしても、全くpri_text
の内容が減ってくれないため、常に'an orangean apple'側が選ばれてしまいます。(なぜあえてpri_text
に一度要素をコピーしているかというと、値だけを得れば後はただのリスト同様、変化してくれるとおもったからです。)
solid_text
の方は、しっかりpop
の効果が働いているのに対して、なぜvalue_text
イテレータ型から取られた、text
変数は、(別の変数に値をうつしたとしても、)pop
の影響を受けないのでしょうか?
そして、これを解決するいい方法はありませんか?現在ごり押しで結果を得ようとしていますし、そこまでのスキルの持ち主でもないため、エレガントな方法を探しています。なお、
value_text
と、solid_text
は、サンプルコードでは固定長ですが、実際は、可変長ですので、よろしくおねがいします。
(追記)
mjyさんのご指摘により、pri_textをたlistで2回くくってしまったがために、popによる処理が反映されていないということでした。
そこで、これは自己回答として残し、新しい疑問は再度質問として載せようとおもいます。