49

コードの実行

listoflists = []
list = []
for i in range(0,10):
    list.append(i)
    if len(list)>3:
        list.remove(list[0])
        listoflists.append((list, list[0]))
print listoflists

戻り値

[([7, 8, 9], 0), ([7, 8, 9], 0), ([7, 8, 9], 0), ([7, 8, 9], 1), ([7, 8, 9], 2), ([7, 8, 9], 3), ([7, 8, 9], 4), ([7, 8, 9], 5), ([7, 8, 9], 6), ([7, 8, 9], 7)]

したがって、どういうわけか、各タプル(リスト)の最初の引数はリストのリストで毎回更新されますが、2番目の引数list[0]は更新されません。誰かがここで何が起こっているのかを説明し、これを修正する方法を提案できますか?出力したい

[([0],0), ([0,1],0), ...
4

7 に答える 7

52

リストは変更可能なタイプです-コピーを作成するには(同じリストを渡すだけでなく)、明示的に行う必要があります。

listoflists.append((list[:], list[0]))

ただし、listこれはすでにPython組み込みの名前です。変数には、その名前を使用しない方がよいでしょう。list変数名として使用せず、コピーを作成するバージョンは次のとおりです。

listoflists = []
a_list = []
for i in range(0,10):
    a_list.append(i)
    if len(a_list)>3:
        a_list.remove(a_list[0])
        listoflists.append((list(a_list), a_list[0]))
print listoflists

上記のリストのコピーを作成する2つの異なる方法を示したことに注意してください:[:]list()

1つ目は、スライス[:](通常はリストの一部だけを取得するために使用されることが多い)を作成することです。これには、たまたまリスト全体が含まれているため、事実上リストのコピーになります。

2番目の、list()は、実際のlist 型コンストラクターを使用して、最初のリストと同じ内容の新しいリストを作成します。(最初の例では、コードでその名前を上書きしていたため、使用しませんでした。これは、それを実行したくない理由の良い例です!)

于 2012-07-14T20:19:27.670 に答える
25

私はPythonと怠惰に慣れていないのでここに来たので、2つのリストのリストを作成する例を探していましたが、しばらくすると、ここのトピックが間違っている可能性があることに気付きました...これはリストのリストを作成するコードです:

listoflists = []
for i in range(0,2):
    sublist = []
    for j in range(0,10)
        sublist.append((i,j))
    listoflists.append(sublist)
print listoflists

これは出力[[(0、0)、(0、1)、(0、2)、(0、3)、(0、4)、(0、5)、(0、6)、(0、 7)、(0、8)、(0、9)]、[(1、0)、(1、1)、(1、2)、(1、3)、(1、4)、(1、 5)、(1、6)、(1、7)、(1、8)、(1、9)]]

コードの問題は、リストを使用してタプルを作成していて、コピーではなくリストへの参照を取得しているようです。タプルトピックに分類されると思います...

于 2014-09-29T23:55:48.803 に答える
13

まず、変数の名前を別の名前に変更することを強くお勧めしますlistlistは組み込みのリストコンストラクターの名前であり、通常の関数を非表示にしています。以下で名前を変更listaます。

Python名は、オブジェクトにバインドされる参照です。つまり、複数のリストを作成しない限り、使用aするときは常に、前回と同じ実際のリストオブジェクトを参照しているということです。だからあなたが電話するとき

listoflists.append((a, a[0]))

後で変更できa、そのタプルの最初の要素が指すものが変更されます。a[0]が指すオブジェクト(整数)は変更されないため、これは発生しa[0]ません(ただしa[0]、コードの実行中に別のオブジェクトを指す)。

コンストラクターを使用して、リスト全体のコピーを作成できます。alist

listoflists.append((list(a), a[0]))

または、スライス表記を使用してコピーを作成できます。

listoflists.append((a[:], a[0]))
于 2012-07-14T20:18:55.403 に答える
3

コードを実行すると

listoflists.append((list, list[0]))

あなたは(私があなたが期待しているように)listの終わりにのコピーを追加していませんlistoflists。あなたがしているのはlist、の最後にへの参照を追加することですlistoflists。したがって、を更新listするたびに、へのすべての参照が更新されますlist。この場合は、のすべてのアイテムです。listoflists

代わりにできることは次のようなものです。

listoflists = []
for i in range(1, 10):
    listoflists.append((range(i), 0))
于 2012-07-14T20:20:02.960 に答える
3

リスト変数(より賢明な名前に変更することをお勧めします)は、変更可能なリストオブジェクトへの参照です。

ライン上

listoflists.append((list, list[0]))

実際には、リスト変数によってオブジェクト参照への参照を追加するだけです。リストのコピーを作成する可能性は複数あるため、listoflistsには、期待どおりの値が含まれています。

コピーライブラリを使用する

import copy
listoflists.append((copy.copy(list), list[0]))

スライス表記を使用する

listoflists.append((list[:], list[0]))
于 2012-07-14T20:26:09.400 に答える
2

また、if句内でのみlistoflistsに追加する限り、期待する出力を取得することはできません。

代わりに次のようなものを試してください。

import copy

listoflists = []
list = []
for i in range(0,10):
    list.append(i)
    if len(list)>3:
        list.remove(list[0])
    listoflists.append((copy.copy(list), copy.copy(list[0])))
print(listoflists)
于 2012-07-14T20:21:42.873 に答える
2

ここのタイムトラベラー

List_of_list =[([z for z in range(x-2,x+1) if z >= 0],y) for y in range(10) for x in range(10)]

これでうまくいくはずです。そして出力はこれです:

[([0], 0), ([0, 1], 0), ([0, 1, 2], 0), ([1, 2, 3], 0), ([2, 3, 4], 0),  ([3, 4, 5], 0), ([4, 5, 6], 0), ([5, 6, 7], 0), ([6, 7, 8], 0), ([7, 8, 9], 0), ([0], 1), ([0, 1], 1), ([0, 1, 2], 1), ([1, 2, 3], 1), ([2, 3, 4], 1), ([3, 4, 5], 1), ([4, 5, 6], 1), ([5, 6, 7], 1), ([6, 7, 8], 1), ([7, 8, 9], 1), ([0], 2), ([0, 1], 2), ([0, 1, 2], 2), ([1, 2, 3], 2), ([2, 3, 4], 2), ([3, 4, 5], 2), ([4, 5, 6], 2), ([5, 6, 7], 2), ([6, 7, 8], 2), ([7, 8, 9], 2), ([0], 3), ([0, 1], 3), ([0, 1, 2], 3), ([1, 2, 3], 3), ([2, 3, 4], 3), ([3, 4, 5], 3), ([4, 5, 6], 3), ([5, 6, 7], 3), ([6, 7, 8], 3), ([7, 8, 9], 3), ([0], 4), ([0, 1], 4), ([0, 1, 2], 4), ([1, 2, 3], 4), ([2, 3, 4], 4), ([3, 4, 5], 4), ([4, 5, 6], 4), ([5, 6, 7], 4), ([6, 7, 8], 4), ([7, 8, 9], 4), ([0], 5), ([0, 1], 5), ([0, 1, 2], 5), ([1, 2, 3], 5), ([2, 3, 4], 5), ([3, 4, 5], 5), ([4, 5, 6], 5), ([5, 6, 7], 5), ([6, 7, 8], 5), ([7, 8, 9], 5), ([0], 6), ([0, 1], 6), ([0, 1, 2], 6), ([1, 2, 3], 6), ([2, 3, 4], 6), ([3, 4, 5], 6), ([4, 5, 6], 6), ([5, 6, 7], 6), ([6, 7, 8], 6), ([7, 8, 9], 6), ([0], 7), ([0, 1], 7), ([0, 1, 2], 7), ([1, 2, 3], 7), ([2, 3, 4], 7), ([3, 4, 5], 7), ([4, 5, 6], 7), ([5, 6, 7], 7), ([6, 7, 8], 7), ([7, 8, 9], 7), ([0], 8), ([0, 1], 8), ([0, 1, 2], 8), ([1, 2, 3], 8), ([2, 3, 4], 8), ([3, 4, 5], 8), ([4, 5, 6], 8), ([5, 6, 7], 8), ([6, 7, 8], 8), ([7, 8, 9], 8), ([0], 9), ([0, 1], 9), ([0, 1, 2], 9), ([1, 2, 3], 9), ([2, 3, 4], 9), ([3, 4, 5], 9), ([4, 5, 6], 9), ([5, 6, 7], 9), ([6, 7, 8], 9), ([7, 8, 9], 9)]    

これはリスト内包表記によって行われます(これにより、1行のコードを介してリスト内の要素をループさせることが可能になります)。この1行のコードの背後にあるロジックは次のとおりです。

(1)範囲(10)のxおよび範囲(10)のyは、リスト内の2つの独立したループに使用されます。

(2)(リスト、y)はループの一般的な用語であるため、(1)の2つのforの前に配置されます。

(3)(2)のリストの長さは3を超えることはできず、リストはxに依存するため、

[z for z in range(x-2,x+1)] 

使用されている

(4)zはゼロから始まりますが、range(x-2、x + 1)は-2から始まるため、これは必要なことではありません。したがって、z> = 0の場合の条件ステートメントは、( 2)

[z for z in range(x-2,x+1) if z >= 0] 
于 2018-07-30T06:58:37.593 に答える